Skip to main content
Version: v0.7.x

EmojiPicker

EmojiPicker is a full React Native emoji keyboard: 1,906 emojis in 9 categories, keyword search, skin tones, recently used, a category bar, and filtering by Emoji version so older devices never show empty boxes. Emojis render with the system font; no images or fonts are bundled.

import { EmojiPicker } from '@elik56a/react-native-pickers';
Result
Loading...
Live Editor
import { useState } from 'react';
import { Text } from 'react-native';
import { EmojiPicker } from '@elik56a/react-native-pickers';

export default function Example() {
  const [text, setText] = useState('Hello ');
  return (
    <>
      <Text style={{ fontSize: 24, minHeight: 36, marginBottom: 8 }}>{text}</Text>
      <EmojiPicker onSelect={(emoji) => setText((t) => t + emoji)} />
    </>
  );
}

Try the props​

categoryBarPosition
columns
<EmojiPicker onSelect={insert} />

onSelect​

onSelect: (emoji: string, data: Emoji) => void

emoji is the character to insert, with the current skin tone applied. data is the base emoji's metadata:

interface Emoji {
emoji: string; // base character, e.g. 'πŸ‘'
name: string; // 'thumbs up'
keywords: string[]; // search tags
category: EmojiCategory;
version: number; // Emoji version it was introduced in, e.g. 13.1
skins?: string[]; // 5 skin-tone variants (light β†’ dark) when supported
}

Categories​

type EmojiCategory = 'smileys' | 'people' | 'animals' | 'food' | 'travel' | 'activities' | 'objects' | 'symbols' | 'flags';

categories filters and orders the sections and the category bar:

Result
Loading...
Live Editor
import { EmojiPicker } from '@elik56a/react-native-pickers';

export default function Example() {
  return <EmojiPicker height={300} categories={['food', 'animals', 'activities']} onSelect={() => {}} showSkinTones={false} />;
}

Hide specific characters with exclude={['πŸ–•', 'πŸ†']}.

The search field matches names and keywords, ranks name-prefix matches first, and requires every word to match (cat face β†’ 🐱). Search across a custom list in your own UI with searchEmojis.

Skin tones​

The βœ‹ button next to search opens a tone menu. Tones are numbers:

type SkinTone = 0 | 1 | 2 | 3 | 4 | 5; // 0 = default yellow, 1–5 = light β†’ dark

Tones apply to every emoji that supports them, in the grid and in what onSelect returns. Control or persist the tone:

const [tone, setTone] = useState<SkinTone>(0);
<EmojiPicker skinTone={tone} onSkinToneChange={setTone} onSelect={insert} />

Use defaultSkinTone for uncontrolled, or showSkinTones={false} to hide the button.

Recently used​

Picked emojis go to a Recently used section at the top (up to maxRecent, default 24, most recent first). The list stores base emojis, so they re-render in whatever tone is current.

The picker keeps recents in memory by default. To persist them across launches, control them:

Persisting recents with AsyncStorage
import AsyncStorage from '@react-native-async-storage/async-storage';

function Picker({ onPick }: { onPick: (e: string) => void }) {
const [recent, setRecent] = useState<string[]>([]);

useEffect(() => {
AsyncStorage.getItem('emoji-recent').then((v) => v && setRecent(JSON.parse(v)));
}, []);

return (
<EmojiPicker
recent={recent}
onRecentChange={(next) => {
setRecent(next);
AsyncStorage.setItem('emoji-recent', JSON.stringify(next));
}}
onSelect={onPick}
/>
);
}

Seed a starter set with defaultRecent={['πŸ‘', '❀️', 'πŸ˜‚']}, or turn the section off with showRecent={false}.

Older devices: maxEmojiVersion​

Emojis newer than the device's font render as empty boxes (common on older Android). Hide them by version:

import { Platform } from 'react-native';

<EmojiPicker
maxEmojiVersion={Platform.OS === 'android' && Platform.Version < 30 ? 12 : undefined}
onSelect={insert}
/>

Layout​

Result
Loading...
Live Editor
import { EmojiPicker } from '@elik56a/react-native-pickers';

export default function Example() {
  return (
    <EmojiPicker
      height={340}
      columns={7}
      emojiSize={30}
      categoryBarPosition="bottom"
      showSectionHeaders={false}
      onSelect={() => {}}
    />
  );
}
  • columns (default 8) sets emojis per row. Cells are square and fill the width.
  • emojiSize sets the font size (default about 62% of the cell).
  • height (default 380) is the total height including search and category bar.
  • categoryBarPosition: 'top' (default) or 'bottom'. Hide the bar with showCategoryBar={false}.
  • showSectionHeaders={false} removes the "Smileys & Emotion" style headers.

Translating labels and icons​

Every label is replaceable. The categoryLabels keys are the categories plus recent and search. Icons can be strings (rendered as text) or any React node:

Result
Loading...
Live Editor
import { EmojiPicker } from '@elik56a/react-native-pickers';

export default function Example() {
  return (
    <EmojiPicker
      height={320}
      searchPlaceholder="Rechercher"
      emptyText="Aucun emoji"
      categoryLabels={{
        recent: 'RΓ©cents',
        smileys: 'Smileys et Γ©motions',
        people: 'Personnes',
        animals: 'Animaux et nature',
        food: 'Nourriture',
        travel: 'Voyages',
        activities: 'ActivitΓ©s',
        objects: 'Objets',
        symbols: 'Symboles',
        flags: 'Drapeaux',
        search: 'RΓ©sultats',
      }}
      categoryIcons={{ smileys: 'πŸ™‚', food: 'πŸ₯' }}
      onSelect={() => {}}
    />
  );
}

Custom emoji cells​

renderEmoji(emoji, data, size) replaces the character, for example to render a custom image set like Twemoji:

<EmojiPicker
renderEmoji={(emoji, data, size) => <Image source={{ uri: twemojiUrl(emoji) }} style={{ width: size, height: size }} />}
onSelect={insert}
/>

In a sheet​

<EmojiPickerSheet visible={open} onClose={() => setOpen(false)} onSelect={(e) => setText((t) => t + e)} />

The sheet closes after each pick by default (closeOnSelect={false} to keep it open). β†’ EmojiPickerSheet

In a form field​

EmojiPickerField opens the sheet from a field and shows value, the emoji you keep in state. Use renderTrigger for an icon button instead of a field:

import { EmojiPickerField } from '@elik56a/react-native-pickers';

<EmojiPickerField label="Icon" placeholder="Pick an icon" value={icon} onSelect={setIcon} />

β†’ Picker fields

Props​

PropTypeDefaultDescription
onSelect(emoji: string, data: Emoji) => voidrequiredCalled with the toned character and its metadata.
columnsnumber8Emojis per row.
emojiSizenumber~62% of cellEmoji font size.
heightnumber380Total height.
categoriesEmojiCategory[]all 9Which categories to show, in order.
excludestring[]β€”Characters to hide.
maxEmojiVersionnumberβ€”Hide emojis newer than this Emoji version.
searchablebooleantrueShow the search field.
searchPlaceholderstring'Search emoji'Search hint.
emptyTextstring'No emoji found'Empty search result text.
showCategoryBarbooleantrueShow the category tabs.
categoryBarPosition'top' | 'bottom''top'Tab bar position.
showSectionHeadersbooleantrueSection title rows.
categoryLabelsPartial<Record<EmojiCategory | 'recent' | 'search', string>>EnglishSection and tab labels.
categoryIconsPartial<Record<EmojiCategory | 'recent', ReactNode>>emoji iconsTab icons.
skinToneSkinToneβ€”Controlled tone.
defaultSkinToneSkinTone0Initial tone.
onSkinToneChange(tone: SkinTone) => voidβ€”Tone picked in the menu.
showSkinTonesbooleantrueShow the tone button.
recentstring[]β€”Controlled recents (base characters).
defaultRecentstring[][]Initial recents.
onRecentChange(recent: string[]) => voidβ€”New recents after each pick.
showRecentbooleantrueShow and update recents.
maxRecentnumber24Recents kept.
renderEmoji(emoji: string, data: Emoji, size: number) => ReactNodeβ€”Custom cell content.
styleStyleProp<ViewStyle>β€”Container style.
stylesSlotStyles<EmojiPickerSlot>β€”Slots below.
themeDeepPartial<PickerTheme>β€”Theme override.
testIDstringβ€”Test ID.

Slots​

SlotElement
containerOuter view
headerSearch + tone row
searchInputSearch TextInput
skinToneButton / skinToneMenuTone button / menu
categoryBarTab bar
categoryTab / activeCategoryTabTabs
categoryIndicatorActive-tab underline
sectionHeader / sectionHeaderTextSection titles
emojiCell / emojiTextGrid cells
empty / emptyTextNo search results

Data and utilities​

The emoji data comes from emojibase (MIT) and is parsed lazily on first use. The helpers are exported for your own UIs (reactions bars, :shortcode autocomplete): getAllEmojis, searchEmojis, findEmoji, withSkinTone, EMOJI_CATEGORIES, DEFAULT_CATEGORY_LABELS, DEFAULT_CATEGORY_ICONS. β†’ Emoji utilities