emoji-index
Browse every Unicode emoji by group → subgroup → emoji — the missing index for building emoji pickers, category menus, and search UIs in Python. Built on the official Unicode Emoji data (Emoji 17.0) with version filtering and skin tone grouping included.
Why emoji-index?
The emoji library is excellent for converting between shortcodes and Unicode characters, but it has no concept of emoji groups or subgroups. Its EMOJI_DATA dictionary is a flat mapping from character to metadata — there's no built-in way to browse "all face emojis" or "all food emojis."
emoji-index is a companion to that library, not a replacement: it organizes the same characters into the official Unicode groups and subgroups, so category-based browsing falls out naturally.
When to use it
- Emoji pickers and menus — groups map to tabs, subgroups to sections, emojis to buttons.
- Version-gated emoji sets — ship only emojis a target platform supports (e.g., pin to 13.0 for older devices).
- Curated browsing or datasets — walk emojis in Unicode (CLDR) order, or pull every emoji in a category for analysis.
- Frontend payloads — each
Emojibundles the character, name,:shortcode:alias, and skin tone variants in one JSON-serializable object.
When not to use it
- Just converting shortcodes — if you only need
emojize/demojize, use theemojilibrary directly; this package adds nothing there. - Multi-person groupings —
family,couple with heart, and similar sequences are excluded (see Known Limitations). - Multilingual search or keywords — names and aliases are English-only; CLDR annotations in other languages are out of scope.
- Render support detection — the index reflects the Unicode standard, not what a given OS, browser, or font can actually display.
- Finding emoji inside free text — for detection, segmentation, or stripping emoji from strings, use a regex-based tool instead.
Features
- Hierarchical browsing — 9 groups, 99 subgroups, 1,861 emojis at the default version, following the Unicode standard
- Version filtering — pin the index to any Emoji version from 1.0 to 17.0 for cross-platform compatibility
- Skin tone grouping — variants (👋🏻 👋🏼 👋🏽 👋🏾 👋🏿) nest under their parent emoji instead of cluttering the index
- Picker-ready objects — each emoji carries its character, human-readable name,
:shortcode:alias, and variants - Zero configuration —
from emoji_index import emoji_indexand start browsing
Installation
pip install emoji-index
Requires Python >= 3.10 and emoji >= 2.15.0.
Quick Start
from emoji_index import emoji_index
for group in emoji_index.groups:
for subgroup in emoji_index[group].subgroups:
for emoji in emoji_index[group][subgroup]:
print(f"{emoji.emoji} {emoji.name}")
Output:
😀 grinning face
😃 grinning face with big eyes
😄 grinning face with smiling eyes
😁 beaming face with smiling eyes
😆 grinning squinting face
...
Examples
Build a picker menu
Groups and subgroups map directly onto picker tabs and sections:
from emoji_index import emoji_index
menu = {group: emoji_index[group].subgroups for group in emoji_index.groups}
print(len(menu), "tabs; first tab sections:", menu["Smileys & Emotion"][:5])
# 9 tabs; first tab sections: ['face-smiling', 'face-affection', 'face-tongue', 'face-hand', 'face-neutral-skeptical']
Search by name
hits = [
(e.emoji, e.name)
for group in emoji_index.groups
for subgroup in emoji_index[group].subgroups
for e in emoji_index[group][subgroup]
if "heart" in e.name
][:5]
print(hits)
# [('🥰', 'smiling face with hearts'), ('😍', 'smiling face with heart-eyes'), ('😻', 'smiling cat with heart-eyes'), ('💘', 'heart with arrow'), ('💝', 'heart with ribbon')]
Target an older Emoji version
Only show emojis available on platforms that lag behind the latest release:
from emoji_index import EmojiIndex
picker = EmojiIndex()
picker.set_version("13.0")
count = sum(len(picker[g][s]) for g in picker.groups for s in picker[g].subgroups)
print(count, "emojis at Emoji 13.0") # 1758 emojis at Emoji 13.0 (vs 1861 at 17.0)
Export to JSON
Emoji is a dataclass, so it serializes cleanly for APIs and front ends:
import json
from dataclasses import asdict
first = emoji_index["Smileys & Emotion"]["face-smiling"][0]
print(json.dumps(asdict(first), ensure_ascii=False))
# {"emoji": "😀", "name": "grinning face", "alias": ":grinning_face:", "variants": null}
API Reference
emoji_index
A pre-built singleton instance of EmojiIndex, ready to use out of the box.
from emoji_index import emoji_index
EmojiIndex
The main entry point for browsing emoji.
| Property / Method | Returns | Description |
|---|---|---|
groups |
list[str] |
All top-level emoji group names |
version |
_EmojiVersion |
The currently selected emoji version (e.g., _EmojiVersion.E17_0) |
set_version(version) |
None |
Filter the index to a specific emoji version; raises ValueError for unknown versions |
[group_name] |
EmojiGroup |
Access a group by name; raises KeyError for unknown groups |
Groups
The index contains 9 top-level groups following the Unicode standard (counts at the default version, Emoji 17.0):
| Group | Subgroups | Emojis |
|---|---|---|
| Smileys & Emotion | 16 | 171 |
| People & Body | 16 | 335 |
| Animals & Nature | 8 | 160 |
| Food & Drink | 7 | 131 |
| Travel & Places | 11 | 219 |
| Activities | 5 | 85 |
| Objects | 18 | 266 |
| Symbols | 14 | 224 |
| Flags | 3 | 270 |
Version Filtering
Filter the index to only include emojis available at a specific Unicode Emoji version. This is useful for ensuring compatibility across platforms that may not support the latest emoji.
emoji_index.set_version("13.0")
print(emoji_index.version) # _EmojiVersion.E13_0
Supported versions: 1.0, 2.0, 3.0, 4.0, 5.0, 11.0, 12.0, 12.1, 13.0, 13.1, 14.0, 15.0, 15.1, 16.0, 17.0
The default version is 17.0.
New in Emoji 16.0–17.0 versus 15.1: ballet dancer, distorted face, face with bags under eyes, fight cloud, fingerprint, flag: Sark, hairy creature, harp, landslide, leafless tree, orca, root vegetable, shovel, splatter, treasure chest, trombone.
EmojiGroup
Represents a top-level emoji group (e.g., "Smileys & Emotion").
| Property / Method | Returns | Description |
|---|---|---|
subgroups |
list[str] |
All subgroup names within this group |
[subgroup_name] |
list[Emoji] |
Access emojis in a subgroup; raises KeyError for unknown subgroups |
group = emoji_index["Smileys & Emotion"]
print(group.subgroups)
# ['face-smiling', 'face-affection', 'face-tongue', ...]
emojis = group["face-smiling"]
# [Emoji(emoji='😀', name='grinning face', ...), ...]
Emoji
A dataclass representing a single emoji.
| Field | Type | Description |
|---|---|---|
emoji |
str |
The emoji character |
name |
str |
Human-readable name (e.g., "grinning face") |
alias |
str |
Demojized shortcode (e.g., ":grinning_face:") |
variants |
list[str] | None |
Skin tone variants, if applicable |
Skin Tone Variants
Emojis that support skin tone modifiers have their variants grouped under the parent emoji, rather than appearing as separate entries in the index:
for emoji in emoji_index["People & Body"]["hand-fingers-open"]:
print(f"{emoji.emoji} {emoji.name}")
if emoji.variants:
print(f" variants: {' '.join(emoji.variants)}")
Output:
👋 waving hand
variants: 👋🏻 👋🏼 👋🏽 👋🏾 👋🏿
🤚 raised back of hand
variants: 🤚🏻 🤚🏼 🤚🏽 🤚🏾 🤚🏿
🖐️ hand with fingers splayed
variants: 🖐🏻 🖐🏼 🖐🏽 🖐🏾 🖐🏿
...
FAQ
Why do the counts differ from unicode.org?
Two intentional reductions keep the index picker-friendly: skin tone variants nest under their parent instead of counting separately, and multi-person groupings (e.g., family, couple with heart) are excluded — see Known Limitations.
Where do aliases come from?
From the emoji library's demojize, which is why emoji >= 2.15.0 is required for current shortcodes. If an alias is ever unknown to that library, one is synthesized from the Unicode name so the field is never empty.
How do I follow new Unicode releases?
Emoji data lives in src/emoji_index/data/emoji_data.py (a snapshot of emoji-test.txt) with versions enumerated in src/emoji_index/objects/emoji.py. See CONTRIBUTING.md for the update recipe.
Known Limitations
- Multi-person grouping emojis are not supported, as these require special handling that is at the moment out of scope. See Multi-Person Groupings.
- Hair component modifiers are not presently supported. See Hair Components.
Contributing
Bug reports and pull requests are welcome — especially new-emoji data updates after each Unicode release. See CONTRIBUTING.md for the development setup and the data-update recipe, and check the issue tracker for open tasks.
Changelog
See CHANGELOG.md for release history.
Licensing
This project is released under the Apache 2.0 License. See the license file for the Apache 2.0 License.
The project also contains data from the Unicode Consortium, which is licensed under the Unicode License Agreement. See the LICENSE_UNICODE.txt file for details.
Metadata
Release files for emoji-index 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| emoji_index-0.2.0.tar.gz | 76.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| emoji_index-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 151.7 kB
Release files / emoji_index-0.2.0.tar.gz
| Download URL | emoji_index-0.2.0.tar.gz |
|---|---|
| Size | 76.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
da21805106eab1cfa989ca6b602c18349658aba6507bb8a0e98481024c0323ee
|
|
BLAKE2b-256 checksum How to use checksums |
d7f7e78a2c38b7a394064fe78d127960edfffeb85d69bc80afb52a1ddd660613
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 2, 2026.
Transparency logRelease files / emoji_index-0.2.0-py3-none-any.whl
| Download URL | emoji_index-0.2.0-py3-none-any.whl |
|---|---|
| Size | 75.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
68a93c67f6c0b4552e5cba33a302686b266d9353c1615c68d512266bfa3aeab1
|
|
BLAKE2b-256 checksum How to use checksums |
67fe489aaf445030271baccc83a0eca20acf03246239d2c54349c29fb05f31ba
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 2, 2026.
Transparency log