@korekoi/react-tabler-flags
v0.1.0
Published
Tree-shakeable React components for the Tabler flags set. Artwork from tabler/tabler-flags (MIT, © Paweł Kuna), pipeline modelled on @tabler/icons-react.
Downloads
100
Readme
@korekoi/react-tabler-flags
Tree-shakeable React components for the Tabler flags set — 287 flags (195 countries, 71 territories, 13 unions, 8 other), all 30×24 SVGs, one component per flag.
Built because @tabler/flags-react is effectively unmaintained: its latest
publish is empty, it declares React as a hard dependency (which installs a
nested React 18 and crashes on React 19), its size prop breaks on CSS
lengths, and its styling is baked into the artwork. This package fixes all of
that with a pipeline modelled on the same author's much more mature
@tabler/icons-react.
- React 18 and 19,
reactinpeerDependenciesonly — never a nested copy. - Tree-shakeable: importing one flag costs ~1 KB min+gzip, not 571 KB.
- Deep imports (
@korekoi/react-tabler-flags/flags/FlagItaly) and a dynamic-import map for runtime lookup by country code. - Variants as props (
rounded/square/circle), not baked artwork. - SSR-safe unique clip ids via
useId, correctSVGSVGElementref typing,displayNameon every component, sensible a11y defaults.
Install
npm install @korekoi/react-tabler-flagsRequires React >= 18. No other dependencies.
Quick start
import { FlagItaly, FlagIT } from '@korekoi/react-tabler-flags'; // FlagIT === FlagItaly
<FlagItaly /> // 24px tall, rounded, border + shine
<FlagItaly size={16} /> // 16px tall, 20px wide (5:4 kept)
<FlagItaly size="2rem" /> // 2rem tall, calc(2rem * 1.25) wide
<FlagItaly variant="square" shine={false} border={false} /> // bare artwork
<FlagItaly variant="circle" /> // square-cropped circle
<FlagItaly title="Italy" /> // accessible: <title> + role="img"Props
| Prop | Type | Default | Notes |
| ----------- | ------------------------------------- | ----------- | ------------------------------------------------------------------------------------------------- |
| size | number \| string | 24 | Height. Width follows at 1.25× (1× for circle). Emitted as SVG attributes, so CSS always wins. |
| variant | 'rounded' \| 'square' \| 'circle' | 'rounded' | rounded matches upstream @tabler/flags-react. |
| border | boolean | true | Thin dark outline so light flags don't bleed into the background. |
| shine | boolean | true | Subtle white top-edge highlight, matching upstream's look. |
| title | string | — | Renders <title> + role="img". Omit for decorative flags (aria-hidden is set automatically). |
| ...rest | SVGProps<SVGSVGElement> | — | className, style, data-*, handlers, ref (typed SVGSVGElement) all pass through. |
Every component keeps upstream's class names (tabler-flag,
tabler-flag-italy), so CSS written against @tabler/[email protected]
keeps working.
Deep imports
Each flag is its own published module:
import FlagItaly from '@korekoi/react-tabler-flags/flags/FlagItaly';
import FlagIT from '@korekoi/react-tabler-flags/flags/FlagIT'; // same module, re-exportedTwo aliases exist only as root exports, not as deep imports: FlagNATO and
FlagUN would collide with FlagNato/FlagUn on case-insensitive
filesystems, so import those from the root (or deep-import the primary name).
Picking a flag at runtime
Don't resolve flags from the barrel at runtime — that bundles all 287. Use the dynamic map, which code-splits to one chunk per flag:
import { lazy, Suspense } from 'react';
import dynamicFlagImports, { dynamicFlagImportsByIso } from '@korekoi/react-tabler-flags/dynamic';
const CountryFlag = ({ iso }) => {
const load = dynamicFlagImportsByIso[iso];
if (!load) return null;
const Flag = lazy(load);
return (
<Suspense fallback={null}>
<Flag />
</Suspense>
);
};(Memoize lazy(load) per code in real apps.)
Lists and metadata
import { flagsList, flagIsoToSlug } from '@korekoi/react-tabler-flags/list';
// [{ name: 'FlagItaly', alias: 'FlagIT', slug: 'italy', label: 'Italy',
// category: 'Countries', iso: 'IT' }, ...]FlagName, FlagSlug, FlagCategory and FlagProps types are exported
from the root.
Tree-shaking notes
Named imports from the root are tree-shaken by every modern bundler
(sideEffects: false + per-module ESM output). Importing the entire barrel
(import * as flags) costs ≈570 KB uncompressed — that's all 287 flags and
is unavoidable; prefer named imports or the dynamic map.
Sizing flags (and Tailwind)
Flags are not square — every flag is 30×24 (5:4). size sets the height;
width follows automatically. Because size is emitted as SVG attributes (not
inline styles), any CSS class you apply wins over it.
With Tailwind, size-* letterboxes a 5:4 flag inside a square. Use the
bundled plugin instead, which mirrors the spacing scale at the correct ratio:
// tailwind.config.js (v3)
plugins: [require('@korekoi/react-tabler-flags/tailwind')],/* app.css (v4) */
@plugin "@korekoi/react-tabler-flags/tailwind";<FlagItaly className="flag-6" /> // 24px tall, 30px wide
<FlagItaly className="flag-4 md:flag-8" /> // responsive variants work
<FlagItaly variant="circle" className="size-6" /> // circles ARE square — size-* is right hereAvoid h-6 w-auto: an <svg> with auto width fills its container instead of
sizing from its ratio. The safe fluid direction is w-full h-auto.
Migrating from @tabler/[email protected]
- Export names are compatible (
FlagIT,FlagUS, …) — imports are mostly mechanical. Flags without an ISO code use their full name (FlagChequered). - Delete any React
overrides/resolutionshack — this package has nodependencies. - The default look matches upstream (rounded, border, shine).
sizenow accepts CSS lengths; numeric behaviour is unchanged.- Refs are now correctly typed as
SVGSVGElement.
Development
npm run generate # flags/*.svg + flags.json -> src/ (generated, gitignored)
npm test # vitest: props matrix, regressions, 287 snapshots, typecheck
npm run build # rollup esm/cjs + d.ts/d.cts, then structural verification
npm run attw # arethetypeswrong against the packed tarball
npm run size # size budget check
npm run smoke # pack + clean install against React 18 and 19 + SSR render
npm run sync-upstream # refresh vendored artwork from tabler/tabler-flags
npm run demo # build demo/index.html with all 287 flagsThere's a full integration fixture in
examples/vite-tailwind — a Vite + React 19 +
Tailwind v4 app installed from the packed tarball:
npm run example:refresh # build + pack + install the library into the example
npm run example:dev # play with it locally
npm run example:verify # bundle assertions + headless Chrome checks (runs in CI)License and attribution
MIT. Flag artwork is from tabler/tabler-flags and the build pipeline is derived from tabler/tabler-icons, both MIT © Paweł Kuna — see NOTICE. This project is not affiliated with or endorsed by Tabler.
