country-flag-emoji-polyfill
Restores color country flag emojis on Chromium browsers under Windows by injecting a tiny web font only when needed.
Repository Health
Technical Analysis
Recent Windows releases finally support color emojis natively, but Windows (and by extension every Chromium-based browser — Chrome, Edge, Brave) still does not render country flag emojis. Instead of a flag, users see a two-letter region code like “CH”. country-flag-emoji-polyfill fixes this with a single function call: it detects whether the browser supports color emojis but not country flags, and if so, injects a <style> tag that loads a subsetted web font scoped to exactly the country-flag unicode range via unicode-range, so it never affects any other character on the page.
The library is deliberately minimal — 0.7kB gzipped with zero runtime dependencies — and the 77kB font asset is only downloaded by browsers that actually need it, via a CDN-hosted .woff2 file. It ships as both an ESM and CJS build with TypeScript types, and is maintained by TalkJS, a chat API/UI vendor that uses it in production and sponsors its upkeep.
What You Get
- A single
polyfillCountryFlagEmojis()function that does feature detection and font injection in one call - A canvas-based emoji-support detector (
supportsEmoji) that renders a glyph to a 1x1 canvas and compares colors to determine if it rendered as a real color emoji - A pre-built, subsetted “Twemoji Country Flags” WOFF2 font (77kB) containing only the glyphs needed for flag emojis, hosted on a CDN and lazy-loaded
- A
unicode-range-scoped@font-faceinjection so the fallback font never interferes with any other character on the page - Both ESM (
dist/index.mjs) and CJS (dist/index.cjs) builds with bundled TypeScript type definitions - A no-build-tool usage path via a plain
<script type="module">tag served from the Skypack CDN
Common Use Cases
- Web apps with country selectors or locale pickers that render flag emojis and need them to look right for Windows Chrome/Edge users
- Chat and messaging products (its original use case at TalkJS) where users send flag emojis in conversations
- E-commerce or SaaS dashboards showing country/region indicators next to user or currency data
- Any site whose CSS already lists a color-emoji font stack and wants a drop-in fix for the Windows Chromium flag gap without extra tooling
Under The Hood
Architecture
The library is two small TypeScript modules with a clean separation of concerns: src/emoji.ts owns feature detection (supportsEmoji), rendering a test glyph to a 1x1 canvas in both black and white fill and comparing the resulting pixel colors to infer whether the browser rendered a real color emoji or a fallback glyph; src/index.ts owns the side effect, calling that detector for a plain emoji and a flag emoji, and if the gap is confirmed, appending a <style> element with an @font-face rule scoped via unicode-range to just the flag codepoints. There is no state, no build-time configuration beyond two optional function parameters, and nothing would meaningfully change if the core abstraction changed — it is a single-purpose runtime check plus a single DOM mutation.
Tech Stack
Written in TypeScript with zero runtime dependencies. Built with unbuild (unbuild --minify) into dual ESM/CJS output plus .d.ts types, matching modern npm dual-package conventions declared via the exports map in package.json. The only devDependencies are unbuild and nodemon (for a dev watch script). The accompanying WOFF2 font asset is generated out-of-band by a shell script (build/make-font.sh) that downloads the Twemoji Mozilla font and subsets it with Python’s fonttools/pyftsubset to just the flag-emoji unicode ranges, then that font is published to and served from a CDN (jsDelivr) rather than bundled into the npm package payload consumers execute.
Code Quality
No automated test suite or CI configuration exists in the repository — correctness relies on manual verification and the small, easily-reasoned-about surface area of the code. What is there is clean: strict TypeScript typing throughout, no any usage in the reviewed source, small single-purpose functions, and unusually thorough inline comments explaining non-obvious browser behavior (e.g. why font-display: swap is used despite its downsides, and how the canvas-based color comparison avoids false positives from partially-transparent fallback glyphs).
API Design
The public API is a single function with two optional parameters (fontName, fontUrl) and a boolean return value, requiring no configuration object, no initialization step, and no framework integration — call it once and it either injects a style tag or does nothing. Documentation is concentrated in the README with copy-pasteable snippets for both the npm and no-build-tool paths, and the required CSS change (prefixing font-family with the polyfill’s font name) is explained with a concrete before/after example, keeping the total integration effort at two small edits.
Used by 3 apps in this directory
Cherry Studio
AI Assistants
All-in-one AI desktop client with 300+ assistants and multi-model support
PostHog
Analytics · Monitoring · Developer Tools
The all-in-one open source product platform combining analytics, session replay, feature flags, error tracking, AI observability, and a built-in data warehouse in a single self-hostable stack.
Uptime Kuma
Monitoring
Self-hosted monitoring for every service you run — 23 monitor types, 95 notification channels, live dashboards, and public status pages with no vendor lock-in.