country-flag-icons
country-flag-icons is an asset package of simplified SVG flags keyed by uppercase country codes. It supplies 3:2 flags, 1:1 crops, React components, raw SVG strings, a CSS class sheet with inline data URLs, Unicode regional-indicator emoji, and small helpers for checking or listing supported codes. Coverage starts with ISO 3166-1 and adds selected reservations, user-assigned regions, and subdivisions. It does not supply country names, translations, dialing codes, political-status logic, or a country selector UI.
country-flag-icons is a good install when you want small, consistent SVG flags and can choose a narrow import path. Do not mistake the icon list for authoritative country data, and avoid the all-flags CSS when only a handful of flags appear.
Use it if
- You need consistent small-screen SVG flags in React, CSS, HTML images, or server-generated markup
- Your data already contains uppercase country codes and you only need to validate whether an icon exists
- You want individual subpath imports so a screen can ship only the flags it displays
- You need both 3:2 artwork and square crops from the same visual set
- You need official, highly detailed artwork: the README says these flags are deliberately minimal and optimized for small on-screen sizes
- You need purpose-designed square flags: the package describes its 1:1 set as crops of the 3:2 artwork, not custom square compositions
- You want every code to mean an official country: the documented list also includes exceptional reservations, user-assigned codes, and selected ISO 3166-2 subdivisions
- You plan to import the all-flags CSS on a small page: the published 3x2 flags.css is 200,897 bytes before compression because every SVG is embedded as a data URL
- You expect emoji flags to render consistently: the README warns that older systems can show missing glyphs or two-letter codes instead of flags
Setup reality
npm install country-flag-icons has no install scripts, runtime dependencies, native builds, credentials, or project config. The main choice is which published surface to use. React projects should already install React even though version 1.6.20 does not declare it as a dependency or peer; the component files import react at runtime. Named imports from country-flag-icons/react/3x2 are convenient when your bundler tree-shakes reliably, while country-flag-icons/react/3x2/US is the safer one-flag import for older tooling. The same structure exists under react/1x1 and string/3x2. Both ESM and CommonJS conditions are exported and TypeScript declarations are included. The raw SVG files exist inside the npm archive, but package exports do not expose country-flag-icons/3x2/US.svg as a JavaScript subpath, so copy assets during your build or use the documented hosted mirrors rather than assuming a bundler import will work. The all-flags CSS embeds the entire set and uses class names such as flag:US plus --CountryFlagIcon-height; that is simple but much heavier than a few components or image URLs. Always supply an alt label for img or an accessible name for SVG components because a flag alone is not a country name. Normalize application input to uppercase, call hasFlag before constructing a URL or import map lookup, and decide how to handle non-ISO additions such as XK, XA, XO, XC, EU, and subdivision codes. The library provides pictures and code availability, not geopolitical policy or localized labels.
Patterns
Render an accessible React flagrender-react-flag
import { US } from 'country-flag-icons/react/3x2';
export function CountryBadge() {
return <US role="img" aria-label="United States" style={{ width: 30 }} />;
}A flag is visual decoration unless it has an accessible name; do not rely on users inferring a country from artwork alone.
Import one React component directlyimport-one-react-flag
import US from 'country-flag-icons/react/3x2/US';
const icon = <US title="United States" className="country-icon" />;The per-country subpath avoids depending on tree shaking of the generated all-country entry point.
Render a 1:1 croprender-square-crop
import JP from 'country-flag-icons/react/1x1/JP';
const avatarFlag = <JP role="img" aria-label="Japan" width={32} height={32} />;The 1:1 assets are crops of the 3:2 designs, not separately composed square flags.
Validate external country codesvalidate-country-code
import { hasFlag } from 'country-flag-icons';
const code = String(input).trim().toUpperCase();
const safeCode = hasFlag(code) ? code : null;Uppercase before checking. The supported set includes documented non-ISO and subdivision codes, so availability is not the same as ISO membership.
Build options from supported codeslist-supported-codes
import { countries } from 'country-flag-icons';
const options = countries
.filter((code) => countryNames[code])
.map((code) => ({ code, label: countryNames[code] }));The package supplies codes, not localized names; join it with your own reviewed country-name source.
Use a documented hosted SVG mirrorrender-hosted-svg
const code = 'CA';
const src = `https://purecatamphetamine.github.io/country-flag-icons/3x2/${code}.svg`;
const image = <img src={src} alt="Canada" width="30" height="20" />;Validate code with hasFlag before building the URL, and self-host if availability, caching, or a content-security policy rules out a third-party mirror.
Render a flag with the CSS bundleuse-css-flags
import 'country-flag-icons/3x2/flags.css';
export function Flag() {
return <span className="flag:DE" role="img" aria-label="Germany" />;
}This import includes every embedded flag. Prefer individual React, string, or hosted assets when the page shows only a few.
Set CSS flag heightsize-css-flag
.country-row .flag\:FR {
--CountryFlagIcon-height: 24px;
}
The colon in the class name must be escaped in a CSS selector; width follows the 3:2 ratio automatically.
Read trusted SVG markup as a stringget-svg-string
import { GB } from 'country-flag-icons/string/3x2';
const html = `<span class="flag-wrap">${GB}</span>`;The exported package constant is trusted static markup; do not generalize this pattern to user-supplied SVG strings.
Import one SVG string directlyimport-one-svg-string
import US from 'country-flag-icons/string/3x2/US';
console.log(US.startsWith('<svg'));The individual string subpath keeps the import explicit when server rendering or a non-React template needs inline SVG.
Convert a country code to Unicode emojirender-unicode-flag
import getUnicodeFlagIcon from 'country-flag-icons/unicode';
import { hasFlag } from 'country-flag-icons';
const code = 'AU';
const flag = hasFlag(code) ? getUnicodeFlagIcon(code) : '🏳';Unicode regional indicators can render as emoji, letters, or missing glyphs depending on the operating system and font.
Map runtime codes to selected componentsmap-dynamic-react-flags
import { CA, GB, US } from 'country-flag-icons/react/3x2';
const flagByCode = { CA, GB, US };
export function FlagFor({ code, label }) {
const Component = flagByCode[code];
return Component ? <Component role="img" aria-label={label} /> : null;
}An explicit map is predictable for bundlers and prevents arbitrary runtime strings from becoming module paths.
Alternatives
| Package | Registry | Pick it when |
|---|---|---|
| flag-icons | npm | Choose it for a CSS-first flag set with 4:3 and 1:1 styles and familiar fi class names |
| react-world-flags | npm | Choose it when a single React component taking a code fits better than generated per-country component exports |
| react-country-flag | npm | Choose it for a small React API that can render SVG or Unicode flags from a country code |
| emoji-flags | npm | Choose it when emoji plus country names and codes are enough and platform-dependent artwork is acceptable |