Your emoji. Your style.
A typed toolkit for creating original product emoji with Codex—or choosing an open provider—then rendering them consistently with smart fallbacks.
Live demo · Custom Emoji · Demo guide · Quick start · Features · Providers · Project config · Semantic tokens · Custom assets · Codex skills · MCP · GitHub Action · Universal web · CLI · AI agents · Build Week
The included $emoji-asset-creator skill turns a visual direction into a validated local emoji provider. This is a first-class product workflow, not a mockup or a hard-coded image.
| 1. Describe | 2. Generate | 3. Validate | 4. Render |
|---|---|---|---|
| Intent, semantic token, and visual direction | Original style anchor reviewed by Codex | Alpha, bounds, centering, format, hash, and provenance | Typed provider with configurable fallback |
$emoji-asset-creator Create a dark 3D robot emoji for agent.ready with one acid-lime spark.
The demo includes a Custom Asset Studio with four original, independently packaged visual directions plus a fifth Create your own / Free Style mode:
| Agent Core | Classic Gloss | Soft 3D | Clay Pop |
|---|---|---|---|
![]() |
![]() |
![]() |
![]() |
agent.ready · 🤖 |
reaction.love · 😍 |
action.launch · 🚀 |
status.idea · 💡 |
Each example maps ordinary Unicode to a generated local asset and falls back to Fluent 3D for the rest of Unicode. The styles are original directions rather than reproductions of proprietary vendor artwork. See the live implementation, complete skill workflow, and custom asset guide.
Free Style is not another preset. Enter any original art direction in natural language—materials, shape language, palette, lighting, mood, or motion—together with a semantic token and Unicode fallback. The lab produces a copy-ready $emoji-asset-creator prompt while retaining only the technical guardrails that make the result work as emoji.
$emoji-asset-creator Create brand.momentum for ☄️ as translucent gel and brushed metal,
with asymmetrical motion, one electric-cyan accent, and soft studio lighting.
Emoji Styles separates emoji meaning from emoji artwork. Your UI keeps ordinary Unicode characters while the renderer decides how they should look. Switch providers without rewriting product copy, preserve accessible fallback text, and share the same URL-resolution core across React, Vue, Svelte, Angular, or vanilla JavaScript.
Every built-in image provider uses artwork with documented redistribution terms and an immutable upstream version. Native mode renders the actual Unicode glyph from the current operating system; it never substitutes a CDN image. See the asset licensing policy.
- ✅ Interchangeable providers — Fluent Emoji, Noto Emoji, SerenityOS pixel art, Twemoji, local assets, and native Unicode
- ✅ Official animation — Microsoft Fluent Animated APNG and opt-in Noto Animated WebP with automatic static fallback
- ✅ Automatic fallback chain — gracefully degrades through providers when images fail to load
- ✅ SSR-safe native lazy loading — complete server markup, browser-native loading, and static styling without hydration drift
- ✅ React component (
<Emoji>) — drop-in component with props for provider, size, alt text, and lazy loading - ✅ Hooks (
useEmoji) — get emoji URLs and metadata for custom UI - ✅ Provider system (
EmojiProvider) — set a default provider at the app level, override per-emoji - ✅ Versioned semantic themes — map stable product intent to localized, accessible emoji or custom icons
- ✅ Automatic text rendering (
<EmojiText>) — transform complete strings, including ZWJ and skin-tone sequences - ✅ Unicode Emoji 17.0 data — 3,953 RGI entries, canonical aliases, and complete sequence metadata from the official Unicode dataset
- ✅ Framework-agnostic core — URL generation, emoji data, and fallback logic work in Vue, Svelte, Angular, or vanilla JS
- ✅ Universal web package — Web Component, CSP-friendly SSR markup, semantic tokens, and reversible DOM transformation
- ✅ Project auditor and safe codemods — AST-based JS/TS/JSX/TSX/HTML findings with terminal, JSON, SARIF, dry-run patches, and validated rollback
- ✅ Deterministic custom-asset pipeline — crop, center, normalize, hash, validate, review, and package product-owned or generated artwork
- ✅ Codex-ready workflows — repository integration and custom asset creation skills with deterministic CLI wrappers
- ✅ Local MCP server — 14 structured tools for resolution, audits, migrations, custom assets, licensing, and opt-in GPT-5.6 semantic analysis
- ✅ Reusable GitHub Action — enforce project policy with line annotations, bounded outputs, job summaries, and SARIF 2.1.0
- ✅ Interactive product studio — build semantic themes, inspect audit fixes, compare providers, and verify reproducibility without rebuilding the repository
- ✅ Self-hosted Twemoji assets — bundle Twemoji PNGs with your app, no CDN dependency
- ✅ TypeScript strict mode — full type safety across all packages
- ✅ ESM output — works with modern bundlers (Vite, Webpack, esbuild)
The demo is an interactive developer workspace rather than a static landing page. It connects six product surfaces in one judge-friendly flow:
Open the live demo at emoji-styles.space
- Custom Asset Studio — see original emoji become validated local providers, or write a free-form visual direction.
- Semantic Theme Builder — turn product intent, fallback Unicode, accessible labels, and provider policy into copy-ready code.
- Audit Flow — compare a raw emoji implementation with the accessible, policy-compliant semantic-token fix.
- Reproducibility View — inspect dataset versions, delivery mode, provider licenses, hashes, and CI evidence.
- Provider Explorer — compare real renderer output across the complete Emoji 17 dataset and copy integration code.
- Framework Examples — review equivalent React, Vue, Svelte, and Angular usage.
See the demo guide for local commands and a concise walkthrough suitable for the Build Week video.
| Provider | Reference | Availability | Format |
|---|---|---|---|
| Fluent Emoji Animated | publicProviders.fluentAnimated |
Public · MIT · pinned revision | Animated PNG |
| Fluent Emoji 3D | publicProviders.fluent3d |
Public · MIT | PNG |
| Fluent Emoji Color | publicProviders.fluentColor |
Public · MIT | SVG |
| Fluent Emoji Flat | publicProviders.fluentFlat |
Public · MIT | SVG |
| Noto Emoji | publicProviders.noto |
Public · Apache 2.0 | PNG |
| Noto Animated (preview) | experimentalProviders.notoAnimated |
Public · CC BY 4.0 · rolling CDN | Animated WebP |
| SerenityOS Pixel Art | publicProviders.serenityOS |
Public · BSD-2-Clause · pinned revision · partial | PNG |
| Twemoji CDN | publicProviders.twemoji |
Public · CC BY 4.0 | PNG |
| Twemoji Local | localTwemojiProvider |
Public · separate asset package | PNG |
| Native Unicode | publicProviders.native |
Current OS/browser | Native |
import { Emoji, publicProviders } from "react-emoji-styles";
<Emoji emoji="🔥" provider={publicProviders.fluent3d} />
<Emoji emoji="🚀" provider={publicProviders.fluentAnimated} />
<Emoji emoji="🚀" provider={publicProviders.noto} />
<Emoji emoji="🚀" provider={publicProviders.serenityOS} size={32} />
<Emoji emoji="✨" provider={publicProviders.native} />SerenityOS resolves only exact PNG matches from its pinned upstream snapshot: 1,800 of the current 3,953 RGI sequences. Missing variants, including skin-tone sequences without their own artwork, continue through the configured fallback chain instead of reusing semantically different base artwork. React and Web package styles apply image-rendering: pixelated while preserving the requested dimensions. For sharper source-pixel scaling, prefer integer multiples of the original glyph dimensions.
Core-only consumers control their own image markup and should opt into pixel rendering explicitly:
.serenityos-emoji {
image-rendering: pixelated;
}Fluent Animated uses Microsoft's official MIT-licensed APNG collection at a pinned revision. Its catalog is intentionally partial, so unsupported emoji continue through the normal fallback chain. Animated Noto assets are a separate preview opt-in because Google serves that collection from a rolling latest endpoint:
import { Emoji, experimentalProviders } from "react-emoji-styles";
<Emoji emoji="🚀" provider={experimentalProviders.notoAnimated} size="3xl" />When an animation is unavailable, the React component continues through its normal fallback chain.
npm install react-emoji-stylesimport { Emoji, publicProviders } from "react-emoji-styles";
import "react-emoji-styles/styles.css";
export function Celebration() {
return <Emoji emoji="🎉" provider={publicProviders.twemoji} size="xl" label="Celebration" />;
}That's it. The <Emoji> component renders a Twemoji PNG image with proper alt text, automatic lazy loading, and fallback to native Unicode if the image fails.
import { Emoji, EmojiProvider, publicProviders } from "react-emoji-styles";
<EmojiProvider provider={publicProviders.fluent3d}>
<Emoji emoji="🔥" /> {/* Uses Fluent 3D by default */}
<Emoji emoji="✨" size={48} />
<Emoji emoji="🚀" provider={publicProviders.noto} /> {/* Override per emoji */}
</EmojiProvider>The repository's $emoji-asset-creator skill produced this original agent.ready asset as a real end-to-end example—not a mockup:
Codex defined the asset specification, generated and reviewed one style anchor, removed its chroma background, normalized it to a centered 256×256 lossless WebP, validated alpha and safe-area occupancy, calculated its SHA-256 hash, and generated the provider manifest plus provenance.
import { Emoji } from "react-emoji-styles";
import { customEmojiProvider } from "./custom-emoji/custom-emoji/runtime";
<Emoji
emoji="🤖"
provider={customEmojiProvider}
label="AI agent ready"
size="3xl"
/>The provider maps 🤖 to the custom artwork and delegates every unmapped emoji to Fluent 3D. The demo also exposes it as the semantic token agent.ready. Its generated-artwork ownership and redistribution status deliberately remain marked user confirmation required; generation and technical validation do not establish legal clearance.
Keep interface meaning stable while themes control the Unicode fallback, provider, localization, or exact product asset:
import {
EmojiProvider,
EmojiToken,
defineEmojiTheme,
publicProviders,
} from "react-emoji-styles";
const productTheme = defineEmojiTheme({
"status.success": {
emoji: "✅",
label: "Operation succeeded",
labels: { es: "Operación exitosa" },
},
"action.deploy": {
emoji: "🚀",
label: "Deploy application",
asset: { url: "/icons/deploy.svg", format: "svg" },
},
}, {
id: "product",
version: "1.0.0",
defaultProvider: publicProviders.fluent3d,
});
<EmojiProvider theme={productTheme} locale="es">
<EmojiToken token="action.deploy" size="lg" />
</EmojiProvider>Themes support inheritance, composition, provider registries, JSON/TypeScript serialization, schema validation, and schema-less v0 migration. See Semantic emoji tokens.
Override only the tokens your product owns. Every other emoji uses the selected fallback provider:
import {
EmojiText,
createMappedProvider,
publicProviders,
} from "react-emoji-styles";
const productIcons = createMappedProvider({
assets: {
"🚀": "/icons/deploy.svg",
"✅": "/icons/passed.svg",
},
fallback: publicProviders.fluent3d,
});
<EmojiText provider={productIcons} size="lg">
Build passed ✅ — shipping now 🚀
</EmojiText>EmojiText parses the complete string and preserves ZWJ sequences, variation selectors, and skin tones as single graphemes. A custom mapping can resolve emoji that are not part of the bundled catalog.
For components from a React design system, use the renderer escape hatch:
<EmojiText
renderEmoji={(emoji, fallback) =>
emoji === "🚀" ? <DeployIcon aria-label="Deploy" /> : fallback
}
>
Deploy 🚀 safely 🔥
</EmojiText>Build your own provider for proprietary emoji assets:
import { createCdnProvider } from "emoji-styles";
const companyProvider = createCdnProvider({
id: "company-emoji",
label: "Company Assets",
baseUrl: "https://assets.example.com/emoji/v1",
extension: "png",
visibility: "custom",
});
getEmojiUrl("🚀", companyProvider);For new integrations, resolveEmoji returns the selected asset, provider version, format, license, and every fallback attempt. An unsupported emoji is represented explicitly instead of producing a URL that may 404:
import { publicProviders, resolveEmoji } from "emoji-styles";
const result = await resolveEmoji("", Scan report · 2026-10-01
- ✓ Prohibited terms or links
- ✓ Repository eligibility
- ✓ slopscore.md paperwork
- ✓ Content policy
- ✓ Risk review
From the balcony · 0 of 4 clapped
Schnitzel, Cap'm Slop, Princess and Crusoe read it and passed. Their reasons are on the balcony, with every other verdict.
Critics are accounts on this site with no GitHub account behind them. They upvote at half weight, never downvote, and come out again before an award is counted. Who they are.
report this listing
— log in to report



0 comments
log in to comment.