The modern emoji SDK for the web. Headless and styled React components for emoji pickers, reactions, inline autocomplete, shortcode-to-unicode inputs, and reaction intensity sliders — built on Zag.js state machines, Tailwind CSS v4, and emojibase data.
npm install @emoteer/react
/* your app's main CSS, processed by Tailwind v4 */
@import "tailwindcss";
@import "@emoteer/react/tailwind";
import { EmoteProvider, EmoteListPicker, isLocalEmote } from "@emoteer/react";
export function App() {
return (
<EmoteProvider locale="en">
<EmoteListPicker
onSelect={(e) =>
console.log(isLocalEmote(e) ? `:${e.name}:` : e.unicode)
}
/>
</EmoteProvider>
);
}
Root + subcomponents) so layouts, labels, and styles can be overridden without forking.app/ and Remix.Locale union with IDE autocomplete.--em-* tokens, no Tailwind preflight, so it never overrides consumer base styles.| Package | Purpose | npm |
|---|---|---|
@emoteer/core |
Framework-agnostic loader, shortcode utilities, indexes, and types. Use directly if you're building a non-React UI. | |
@emoteer/theme |
CSS-only design tokens and Tailwind CSS v4 preset. Consumed transitively by @emoteer/react. |
|
@emoteer/react |
Ready-to-use React 19 components (picker, autocomplete, reactions, slider, tooltip, inputs). |
Support for Svelte and Vue is planned — Zag's state machines already run framework-agnostic, so porting the UI layer is the main work.
@emoteer/react).@emoteer/react/tailwind is a preset processed by your app's Tailwind pipeline.The repository is a Turborepo with pnpm workspaces. To work on a single package:
pnpm install
pnpm --filter @emoteer/react build
pnpm --filter @emoteer/react check-types
Or across the whole workspace:
pnpm build
pnpm check-types
pnpm lint
In progress:
@emoteer/svelte — first non-React binding, built on Svelte 5 runesNext:
@emoteer/vue — Vue 3 binding with the same primitive surfaceSee the full roadmap for shipped milestones, items under consideration, and anti-goals.
MIT © vyers