react-country-flag vs react-flags vs react-world-flags
Rendering Country Flags in React Applications
react-country-flagreact-flagsreact-world-flagsSimilar Packages:

Rendering Country Flags in React Applications

react-country-flag, react-flags, and react-world-flags are React components designed to render country flags using ISO country codes. They solve the common problem of displaying localized indicators without managing large asset bundles manually. react-country-flag focuses on performance by using emoji fonts by default and offering SVGs as an opt-in feature. react-flags provides a lightweight wrapper around flag icon sets, often relying on external CSS or SVG imports. react-world-flags is a dedicated SVG renderer that pulls vector assets directly, ensuring crisp scaling at any size but potentially increasing bundle weight if not tree-shaken correctly.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
react-country-flag0-22.9 kB-3 years agoMIT
react-flags08726.7 MB9-MIT
react-world-flags017410.8 MB163 years agoMIT

React Flag Libraries: Architecture, Rendering, and Trade-offs

Displaying country flags seems simple until you consider bundle size, rendering consistency, and accessibility. The three main contendersโ€”react-country-flag, react-flags, and react-world-flagsโ€”take fundamentally different approaches to solving this. Let's break down how they work under the hood and when to use each.

๐ŸŽจ Rendering Engine: Emoji vs. SVG vs. Wrapper

The core difference lies in how these libraries draw the flag. This choice impacts your bundle size, load time, and visual consistency across devices.

react-country-flag defaults to Emoji rendering.

  • It maps country codes (like 'US') to regional indicator symbols (๐Ÿ‡บ๐Ÿ‡ธ).
  • No images or SVGs are loaded. The browser uses the OS's native font.
  • This results in near-zero bundle impact but means the flag looks different on Windows vs. macOS vs. Android.
// react-country-flag: Default emoji mode
import ReactCountryFlag from 'react-country-flag';

// Renders ๐Ÿ‡บ๐Ÿ‡ธ using system font
<ReactCountryFlag countryCode="US" />

react-world-flags uses Inline SVGs.

  • It imports vector data for every country and renders it as an <svg> element.
  • The flag looks identical on every device and scales perfectly.
  • The trade-off is bundle size. Even with tree-shaking, importing the library pulls in vector path data.
// react-world-flags: Pure SVG mode
import Flag from 'react-world-flags';

// Renders a crisp <svg> element
<Flag code="US" style={{ width: '24px', height: '24px' }} />

react-flags often acts as a Wrapper.

  • Depending on the specific variant, it may rely on external CSS classes or require you to host assets.
  • It gives you control over the source but adds configuration overhead.
  • You might end up managing a sprite sheet or a folder of PNGs yourself.
// react-flags: Class-based or asset wrapper
import ReactFlags from 'react-flags';

// Might render an <img> or a <div> with a background class
<ReactFlags country="US" className="my-custom-flag" />

๐Ÿ“ฆ Bundle Impact and Performance

Bundle size is the hidden cost of flag libraries. Including 200+ country assets can bloat your JavaScript bundle significantly.

react-country-flag is the lightest option.

  • In emoji mode, it adds almost nothing to your bundle.
  • If you enable SVG mode, it dynamically loads only the vectors you need (if configured correctly) or imports the set.
  • Best for long lists where rendering 50 flags would otherwise cause layout shifts or memory pressure.
// react-country-flag: Optimized for lists
// Zero network request, instant paint
{countries.map(c => (
  <ReactCountryFlag key={c.code} countryCode={c.code} />
))}

react-world-flags requires careful bundler configuration.

  • Modern bundlers like Webpack or Vite can tree-shake unused countries, but you must verify this in your production build.
  • If tree-shaking fails, you might ship kilobytes of unused vector paths.
  • Ideal for scenarios where you display only a few flags but need them to look perfect.
// react-world-flags: Ensure tree-shaking works
// Check your bundle analyzer to confirm unused codes are removed
<Flag code={dynamicCode} />

react-flags varies by implementation.

  • If it loads a full CSS file or sprite sheet, you pay the cost upfront.
  • If it loads images on demand, you incur network latency for each new country.
  • Suitable for static sites where you can pre-load assets or cache them aggressively.
// react-flags: Potential network latency
// Each new country might trigger a fetch if not preloaded
<ReactFlags country={dynamicCountry} />

๐Ÿ› ๏ธ Styling and Customization

How much control do you have over the look and feel?

react-country-flag offers limited styling in emoji mode.

  • You can change the fontSize to scale the emoji, but you cannot recolor parts of the flag.
  • SVG mode unlocks full CSS control over fills and strokes.
  • Use this when you need to match a specific brand color palette (e.g., grayscale flags).
// react-country-flag: SVG mode for custom colors
<ReactCountryFlag 
  countryCode="FR" 
  svg 
  style={{ fill: '#333', width: '32px' }} 
/>

react-world-flags provides full SVG access.

  • Since it renders standard SVG elements, you can target paths with CSS.
  • You can easily create hover effects, monochrome versions, or responsive scales.
  • This is the most flexible option for design-heavy applications.
// react-world-flags: Full CSS control
<Flag 
  code="DE" 
  className="hover:opacity-80 transition-opacity" 
  style={{ width: '100%', height: 'auto' }} 
/>

react-flags depends on the underlying asset.

  • If using PNGs, you are limited to opacity and filters (like grayscale).
  • If using SVGs, you get similar control to react-world-flags but might need to dig into the DOM structure.
  • Best when you have a pre-existing design system with specific asset requirements.
// react-flags: Filter-based customization
<ReactFlags 
  country="JP" 
  style={{ filter: 'grayscale(100%)' }} 
/>

โ™ฟ Accessibility and Semantics

Flags are images, but screen readers need text descriptions.

react-country-flag handles accessibility automatically.

  • It accepts a title prop that becomes the aria-label or tooltip.
  • In emoji mode, some screen readers might read "Regional Indicator Symbol Letter U..." which is confusing. Always provide a title.
// react-country-flag: Accessible by default
<ReactCountryFlag 
  countryCode="CA" 
  title="Canada" 
  aria-label="Canada" 
/>

react-world-flags requires manual aria management.

  • As an SVG, it needs role="img" and a <title> element inside to be accessible.
  • The library usually supports passing these props, but you must remember to add them.
// react-world-flags: Manual accessibility props
<Flag 
  code="GB" 
  title="United Kingdom" 
  aria-label="United Kingdom" 
  role="img" 
/>

react-flags varies.

  • If it renders an <img>, you need an alt tag.
  • If it renders a <div>, you need aria-label.
  • Check the rendered output to ensure your screen reader setup is correct.
// react-flags: Verify alt text support
<ReactFlags 
  country="AU" 
  alt="Australia" 
/>

๐ŸŒ Real-World Scenarios

Scenario 1: Global User Table

You are displaying a table with 100 rows, each having a user's country.

  • โœ… Best choice: react-country-flag (Emoji mode)
  • Why? Rendering 100 SVGs would strain the DOM. Emojis are text characters and render instantly with no layout shift.
// High-performance list
{users.map(user => (
  <tr key={user.id}>
    <td><ReactCountryFlag countryCode={user.country} /></td>
    <td>{user.name}</td>
  </tr>
))}

Scenario 2: Executive Dashboard

You are building a printed report or a high-DPI dashboard where flags must look crisp at large sizes.

  • โœ… Best choice: react-world-flags
  • Why? Emojis look pixelated or inconsistent when scaled up. SVGs remain sharp and professional.
// High-fidelity display
<div className="dashboard-card">
  <Flag code="US" style={{ width: '64px', height: '64px' }} />
  <h3>Sales Performance</h3>
</div>

Scenario 3: Legacy System Integration

You are working in an environment with strict asset hosting policies and cannot use external CDNs or dynamic imports.

  • โœ… Best choice: react-flags (or self-hosted SVGs)
  • Why? You can bundle the specific assets you need into your public folder and reference them directly, bypassing library logic.
// Controlled asset loading
<ReactFlags 
  country="BR" 
  src="/assets/flags/br.svg" 
/>

๐Ÿ“Š Summary: Key Differences

Featurereact-country-flagreact-world-flagsreact-flags
Default RenderEmoji (Text)Inline SVGWrapper (Img/CSS)
Bundle SizeTiny (Emoji) / Medium (SVG)Medium/Large (Vector Data)Variable
Visual ConsistencyLow (OS Dependent)High (Vector)Medium (Asset Dependent)
Styling ControlLimited (Emoji) / High (SVG)High (Full CSS)Medium
AccessibilityAuto (with title)Manual (ARIA props)Manual (Alt/ARIA)
Best Use CaseLists, Tables, MobileDashboards, Print, BrandingLegacy, Custom Assets

๐Ÿ’ก The Big Picture

react-country-flag is the pragmatic choice for most web apps. It solves the "I need a flag next to this text" problem with zero friction. Start with emoji mode for speed, and toggle SVG mode only if design requirements demand it.

react-world-flags is the specialist tool for visual fidelity. If your application sells a premium feel or needs to support large-scale prints, the vector precision is worth the extra bundle bytes. Just keep an eye on your build size.

react-flags serves niche cases where you need to bridge a gap with existing infrastructure. If you already have a folder of flag assets or a specific CSS framework requirement, this wrapper saves you from writing boilerplate code.

Final Thought: Don't over-engineer flag rendering. For 90% of use cases, the emoji approach in react-country-flag is sufficient. Only reach for SVGs when the visual quality directly impacts user trust or brand perception.

How to Choose: react-country-flag vs react-flags vs react-world-flags

  • react-country-flag:

    Choose react-country-flag if performance and bundle size are your top priorities. It defaults to emoji rendering, which requires zero network requests and minimal JavaScript, making it ideal for lists, tables, or high-frequency renders. Switch to SVG mode only when you need specific styling or consistent rendering across older operating systems that lack emoji support.

  • react-flags:

    Choose react-flags if you are already using a specific icon ecosystem or need a simple wrapper around existing flag assets. This package is suitable for projects where you want to manage the underlying asset source manually or integrate with a specific design system that provides its own flag set. Avoid it if you need a zero-config solution with built-in SVG optimization.

  • react-world-flags:

    Choose react-world-flags if visual fidelity and scalability are critical, such as in dashboards, printed reports, or high-DPI displays. Since it renders pure SVGs, you get crisp edges at any size without relying on the user's OS font support. Be prepared to handle slightly larger bundle sizes or configure tree-shaking to include only the countries your app actually uses.

README for react-country-flag

react-country-flag

React component for emoji/svg country flags.

NPM JavaScript Style Guide

Install

npm install --save react-country-flag

BREAKING CHANGES

v3.x NONE only Typescript Types were introduced, enjoy!

v2.x has breaking changes

  • code is now countryCode
  • title and aria-label are not defined any more, it is up to the developer to pass these in
  • styleProps is now style

Usage

All 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

Detecting Emoji support

Try this out and conditionally render your country flag https://github.com/danalloway/detect-emoji-support

License

MIT ยฉ danalloway