react-country-flag, react-flag-kit, react-flags, and react-flags-select are React libraries that help developers render country flags in web applications. These packages differ significantly in implementation strategy — some use SVG sprites or inline SVGs, others rely on external image assets or CSS background images — which affects bundle size, accessibility, customization, and performance. While all aim to simplify flag display, their APIs, maintenance status, and suitability for production vary widely.
When building internationalized React apps — think user profiles, shipping forms, or language selectors — you’ll often need to show country flags. The four packages under review take very different approaches: some embed SVGs directly, others pull remote images, and one even ships a full country picker UI. Let’s cut through the noise and see what actually works in real projects.
react-flags Is DeadBefore diving into features, let’s address the elephant in the room: react-flags is deprecated. Its npm page states it’s no longer maintained, and its GitHub repo is archived. It loads flags as external PNGs from unpkg, which causes layout shifts and fails offline. Do not use this in new projects. We’ll still compare it for completeness, but treat it as a cautionary tale.
The biggest technical difference lies in how each package delivers flag graphics — and that choice impacts performance, accessibility, and reliability.
react-country-flag uses inline SVGs embedded directly in the bundle. Each flag is a React component generated from SVG paths.
// react-country-flag
import ReactCountryFlag from "react-country-icon";
<ReactCountryFlag countryCode="US" svg style={{ width: '2em' }} />
react-flag-kit also uses inline SVGs, but with more refined vector paths and consistent aspect ratios. It supports both 2-letter (US) and 3-letter (USA) codes.
// react-flag-kit
import { US } from "react-flag-kit";
<US style={{ width: '2em' }} />
react-flags (deprecated) loads external PNGs from a CDN:
// react-flags (avoid)
import Flag from "react-flags";
<Flag name="USA" basePath="/flags" />
// Tries to load /flags/USA.png — breaks if offline or CDN fails
react-flags-select bundles SVGs as data URLs inside CSS background images by default, though it can switch to inline SVGs via the useSvg prop:
// react-flags-select
import ReactFlagsSelect from "react-flags-select";
<ReactFlagsSelect selected="US" onSelect={code => console.log(code)} useSvg />
💡 Key takeaway: Inline SVGs (used by
react-country-flagandreact-flag-kit) avoid network requests, prevent layout shift, and scale cleanly. External images (like inreact-flags) are fragile and slow.
Not all packages handle invalid or missing country codes gracefully.
react-country-flag silently renders nothing if you pass an unsupported code like XX. You must validate inputs yourself:
// No error thrown for invalid code
<ReactCountryFlag countryCode="XX" /> {/* renders empty */}
react-flag-kit throws a clear error during development if you import a non-existent flag:
// This fails at build time if 'XX' doesn't exist
import { XX } from "react-flag-kit"; // Module not found
react-flags-select includes a built-in list of supported countries and ignores invalid selections:
// Invalid code is just ignored
<ReactFlagsSelect selected="XX" /> {/* shows nothing or placeholder */}
react-flags tries to load XX.png and shows a broken image icon — a poor user experience.
Need to tweak colors, sizes, or add borders? Here’s how each package handles it.
react-country-flag accepts a style prop and lets you force SVG mode (which enables CSS styling):
<ReactCountryFlag
countryCode="FR"
svg
style={{
width: '1.5em',
height: '1em',
border: '1px solid #ccc'
}}
/>
react-flag-kit gives you a plain SVG element, so standard CSS works:
.flag {
width: 1.5em;
filter: grayscale(100%); /* easy to modify */
}
<US className="flag" />
react-flags-select offers extensive theming via CSS classes and props like customLabels, but deep styling requires overriding its internal class names:
<ReactFlagsSelect
selected="DE"
selectButtonClassName="my-custom-button"
optionsClassName="my-options-list"
/>
react-flags provides minimal styling control — you’re stuck with whatever the PNG looks like.
Only react-flags-select includes a complete UI component for selecting countries. The others are display-only.
If your use case is “show the user’s country flag next to their name,” any of the display-focused libraries work. But if you need “let users pick their country from a dropdown,” react-flags-select saves you from building a selector from scratch:
// Full country selector with search
<ReactFlagsSelect
searchable
searchPlaceholder="Search countries..."
onSelect={code => setUserCountry(code)}
/>
The trade-off? You’re pulling in extra code for dropdown logic, even if you only need static flags elsewhere in your app.
Screen reader support varies:
react-country-flag adds a <title> element when you pass a title prop:
<ReactCountryFlag countryCode="JP" title="Japan" />
react-flag-kit leaves accessibility up to you — wrap the SVG in a <span aria-label="Japan"> if needed.
react-flags-select includes ARIA labels for its dropdown options automatically.
react-flags offers no built-in accessibility features.
| Scenario | Best Choice |
|---|---|
| Simple flag display with minimal bundle | react-country-flag |
| High-fidelity flags for polished UIs | react-flag-kit |
| Country selection dropdown | react-flags-select |
| New projects (any use case) | Avoid react-flags |
react-flag-kit if visual quality matters, or react-country-flag if you want the smallest possible footprint.react-flags-select is the only complete solution here — just be mindful of its bundle cost.react-flags — it’s outdated, unreliable, and unmaintained.Choose based on whether you need just a flag or a full selection interface, and always validate country codes before rendering to avoid silent failures.
Choose react-country-flag if you need a lightweight, zero-dependency solution that renders flags as inline SVGs using ISO 3166-1 alpha-2 codes. It’s ideal for simple flag displays where accessibility (via title attributes) and minimal bundle impact matter. Avoid it if you require fallback handling for unsupported codes or advanced styling beyond basic props like svg and style.
Do not choose react-flags for new projects. The package is deprecated according to its npm registry entry and GitHub repository archive status. It relies on external PNG assets hosted via unpkg, introduces layout shift due to image loading, and lacks modern accessibility features. Use one of the maintained alternatives instead.
Choose react-flags-select if you need a ready-made country selector dropdown with integrated flag display, search, and localization support. It’s well-suited for forms requiring country input (e.g., phone number or address fields). However, its bundle includes all flag assets by default, so consider lazy-loading or custom builds if bundle size is a concern.
Choose react-flag-kit if you want high-quality, consistent SVG flags with excellent visual fidelity and built-in support for both ISO 2-letter and 3-letter country codes. Its clean API and focus on design quality make it suitable for UIs where visual polish is critical. However, note that it doesn’t include selection UI components — it’s purely for rendering individual flags.
React component for emoji/svg country flags.
npm install --save react-country-flag
v3.x NONE only Typescript Types were introduced, enjoy!
v2.x has breaking changes
code is now countryCodetitle and aria-label are not defined any more, it is up to the developer
to pass these instyleProps is now styleAll props are passed onto the element, everything can be overwritten.
import React from "react"
import ReactCountryFlag from "react-country-flag"
function ExampleComponent {
return (
<div>
<ReactCountryFlag countryCode="US" />
<ReactCountryFlag
className="emojiFlag"
countryCode="US"
style={{
fontSize: '2em',
lineHeight: '2em',
}}
aria-label="United States"
/>
<ReactCountryFlag countryCode="US" svg />
<ReactCountryFlag
countryCode="US"
svg
style={{
width: '2em',
height: '2em',
}}
title="US"
/>
<ReactCountryFlag
countryCode="US"
svg
cdnUrl="https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.4.3/flags/1x1/"
cdnSuffix="svg"
title="US"
/>
</div>
)
}
export default ExampleComponent
Try this out and conditionally render your country flag https://github.com/danalloway/detect-emoji-support
MIT © danalloway