Country Picker

A searchable country select with flags, dial codes, and keyboard filtering.

import { CountryPicker } from "@fern-ui/country-picker"

const [country, setCountry] = useState("IN")

<CountryPicker value={country} onChange={setCountry} />

Search matches four things at once: the country name, the two-letter code, the dial code, and common aliases — so UK, GB, +44 and britain all find the United Kingdom. Diacritics fold, so cote finds Côte d'Ivoire.

Examples

Pinning common countries

198 countries in alphabetical order buries the handful most of your traffic comes from. priority lifts them above the list.

<CountryPicker
  value={country}
  onChange={setCountry}
  priority={["US", "GB", "IN", "DE", "JP"]}
/>

Without dial codes

Turning them off also removes them from the search index, so a query of 44 matches nothing rather than surprising you with the UK.

<CountryPicker value={country} onChange={setCountry} showDialCode={false} />

Flags

By default flags load from a CDN, so bun add works with no setup — a picker whose images 404 until you copy an asset directory is broken out of the box.

The same SVGs ship inside the package. To self-host, copy them across and point flagSrc at your own path:

cp -r node_modules/@fern-ui/country-picker/flags public/flags
<CountryPicker flagSrc={(code) => `/flags/${code}.svg`} />

Each is a 512×512 circle-cropped SVG averaging 0.6KB, loaded lazily — only the rows you scroll to are fetched.

Keyboard

Arrows move, Home and End jump to the ends, PageUp and PageDown move by ten. Enter selects, Escape closes, Tab closes and moves on. The trigger opens on Enter, Space or ArrowDown.

Installation

bun add @fern-ui/country-picker

Or copy these eight files into your project. No runtime dependencies beyond React; every one of them is imported by the component.

country-picker.tsx
Loading country-picker.tsx…
parts.tsx
Loading parts.tsx…
search.ts
Loading search.ts…
keyboard.ts
Loading keyboard.ts…
use-open-state.ts
Loading use-open-state.ts…
use-anchored-position.ts
Loading use-anchored-position.ts…
icons.tsx
Loading icons.tsx…
countries.ts
Loading countries.ts…

Props

PropTypeDefaultDescription
valuestringControlled selection, as an ISO 3166-1 alpha-2 code.
defaultValuestringInitial selection when uncontrolled.
onChange(code, country) => voidFires with the code and the full country record.
countriesCountry[]198 countriesReplace the list — for a subset, or another locale's names.
prioritystring[]Codes pinned above the alphabetical list.
showDialCodebooleantrueShow the dial code badge and allow searching by it.
flagSrc(code) => stringjsDelivr CDNResolves a flag URL from a lowercase country code.
showFlagsbooleantrueOff gives a plain text list, and skips 200 image requests.
placeholderstring"Select a country"Trigger text with nothing selected.
searchPlaceholderstring"Search countries"Placeholder inside the search field.
clearablebooleantrueLet the user clear the selection once one is made.
disabledbooleanfalseBlock interaction and dim the control.
labelstring"Country"Accessible name for the trigger.

On this page