The emoji toolkit for the modern web.
Pickers, reactions, autocomplete and inputs. Headless primitives and styled components. Framework-agnostic core, one source of truth for emojis across your stack.
pnpm add @emoteer/reactDesigned to grow with your stack.
Headless first.
Compound primitives give you full control over markup, ARIA and styling.
Framework agnostic.
Shared core with the same data, matching and state across every binding.
Themeable defaults.
Tailwind-ready styles ship with the library and can be overridden per slot.
Every emoji primitive, in one coherent toolkit.
A searchable emoji picker, ready to ship.
Virtualized grid, tabs per category, shortcode search, keyboard navigation, preview panel. Style it or keep the defaults.
Counters and reaction bars.
Stateful reactions with active states, counts and toggles.
Intensity sliders.
0โ100 emoji sliders for feedback and ratings.
Inline shortcode suggestions.
Type โ:โ in any input to trigger suggestions. Choose from keyboard, click or Tab.
Auto-convert shortcodes to unicode.
Typing :star: becomes โญ the moment you close the shortcode. Works on inputs and textareas.
One core. Every framework.
The @emoteer/core package ships the data, search, matching and state machines. Framework bindings are a thin layer on top.
Data, search & state.
Framework-agnostic logic. Zero DOM dependencies.
One primitive, infinite looks.
Every slot exposes its own CSS variable. Set a few, ship a completely different picker โ no Tailwind required. Bindings are framework-agnostic, themes are too.
Ship a full picker in ten lines.
import { EmoteList, EmoteProvider } from '@emoteer/react';ย export default function App() { return ( <EmoteProvider> <EmoteList.Root onSelect={handleSelect}> <EmoteList.Search /> <EmoteList.Tabs /> <EmoteList.Grid /> </EmoteList.Root> </EmoteProvider> );}Compound API
Every slot is a separate component you can swap, remove or style.
No config required
Defaults render a complete picker. Override only what you need.
Typed end-to-end
First-class TypeScript types for every event and slot.
Frequently asked questions.
Is it production ready?
The React package exposes a stable API. Other framework bindings share the same core and will land behind the same semver guarantees.
Do I need Tailwind?
No. Styled components ship with plain CSS classes. Tailwind is supported out of the box but not required.
What about bundle size?
Tree-shakeable imports keep the picker around 12kb gzipped including the virtualized grid and shortcode matcher.
Can I add custom emojis?
Yes. Pass a locale or a custom emoji list through EmoteProvider. Shortcodes and search integrate automatically.
Which frameworks are supported?
React and Svelte 5 are stable today (@emoteer/react and @emoteer/svelte) with an identical component surface. Vue is on the roadmap โ the framework-agnostic core already ships most of the logic, so the binding stays thin.
Start shipping emojis in minutes.
Open source, MIT licensed, and designed to grow with your stack.