react-country-flag and react-flags are both lightweight React components designed to render country flags using ISO 3166-1 country codes. They abstract away the complexity of managing flag assets and provide a simple, declarative API for displaying national flags in web applications. Both packages rely on emoji-based rendering rather than external image files or SVG sprites, which keeps bundle size minimal and avoids additional network requests.
When you need to show country flags in a React app — maybe for language selectors, user profiles, or international shipping options — you might reach for a small utility package instead of managing SVGs or PNGs yourself. Both react-country-flag and react-flags aim to solve this by rendering flags as emoji, which are built into modern operating systems. But their current state, features, and maintainability differ significantly.
Both libraries use Unicode country flag emojis, which means they don’t ship any image assets. Instead, they convert a country code (like "US") into the corresponding emoji sequence (🇺🇸). This keeps the bundle tiny and avoids extra HTTP requests.
react-country-flag does this reliably and safely:
import ReactCountryFlag from "react-country-flag";
function App() {
return <ReactCountryFlag countryCode="US" />;
}
react-flags uses a similar approach but with fewer safeguards:
import Flag from "react-flags";
function App() {
return <Flag code="US" />;
}
⚠️ Note: Emoji rendering depends on the user’s OS and browser. On older systems or certain platforms (like Linux without emoji fonts), flags may appear as letters (e.g., "US") instead of the flag graphic. Neither package can fix this — it’s a platform limitation.
react-country-flag supports both 2-letter ("US") and 3-letter ("USA") ISO codes. It automatically normalizes input and handles invalid codes gracefully by rendering nothing (or a placeholder if configured).
// Works with 2-letter
<ReactCountryFlag countryCode="FR" />
// Also works with 3-letter
<ReactCountryFlag countryCode="DEU" />
react-flags only accepts 2-letter codes and throws no warnings for invalid inputs. If you pass "USA", it renders nothing silently. There’s no validation or conversion logic.
// Only 2-letter works
<Flag code="JP" />
// This fails silently
<Flag code="JPN" />
react-country-flag includes accessibility attributes by default. You can set alt, title, and aria-label to help screen readers and improve SEO:
<ReactCountryFlag
countryCode="CA"
alt="Canada"
title="Canada"
aria-label="Flag of Canada"
/>
react-flags renders a plain <span> with no accessibility props. You’d have to wrap it yourself or add attributes manually, which defeats the purpose of using a dedicated component.
// No built-in accessibility
<Flag code="BR" />
// Renders: <span>🇧🇷</span>
This is the most critical difference.
react-country-flag is actively maintained. It includes TypeScript definitions, follows semantic versioning, and accepts bug fixes and improvements. The API is stable and well-documented.
react-flags is deprecated. Its npm page and GitHub repository show no updates in over five years. There are open issues about missing features and bugs that will never be addressed. Using it introduces technical debt and potential breakage in future React versions.
react-country-flag ships with full TypeScript support. Your IDE will autocomplete props and validate country codes at compile time:
// TypeScript knows these props
<ReactCountryFlag countryCode="MX" style={{ fontSize: '2rem' }} />
react-flags has no type definitions. You’ll get no IntelliSense, and errors only surface at runtime — if at all.
Use react-country-flag. It’s the only sensible choice for production applications today. It’s lightweight, accessible, flexible with country codes, and actively supported.
Do not use react-flags in new codebases. Its deprecated status, lack of accessibility, and rigid input requirements make it a liability.
If your app only needs a handful of flags and you control the design system, consider using inline emoji directly:
<span role="img" aria-label="United States">🇺🇸</span>
This avoids dependencies entirely. But once you need dynamic country codes, validation, or consistent accessibility, react-country-flag becomes worth the minimal install.
Choose react-country-flag if you need a well-maintained, straightforward component that supports both 2-letter (ISO 3166-1 alpha-2) and 3-letter (ISO 3166-1 alpha-3) country codes with automatic fallback handling. It’s actively maintained, includes TypeScript definitions out of the box, and provides props like alt, title, and aria-label for accessibility without requiring extra configuration.
Avoid react-flags in new projects — it is deprecated and no longer maintained. The package hasn’t been updated in years, lacks TypeScript support, offers no accessibility attributes, and only accepts 2-letter country codes without validation or fallbacks. While it technically works, its unmaintained status poses long-term risks.
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