carpedm20/emoji: converting between Python text codes and Unicode emoji characters
emoji terminal output for Python
At a glance
- What is it?
- carpedm20/emoji is a Python library that converts colon-delimited text codes to Unicode emoji characters and reverses the direction. It supports 13 non-English language code lists and requires Python 3.8 or newer.
- Who is it for?
- Use carpedm20/emoji when a Python application needs to convert between colon-delimited text codes and Unicode characters in either direction, especially when non-English language code lists matter. Skip it when the only requirement is detecting whether a character is an emoji and no external dependency is acceptable.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 25 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 11, 2026, and from our analysis. They are not legal advice.
Editorial analysis
emojize and demojize convert between text codes and Unicode in both directions
Two functions cover most of the library's workload. emoji.emojize() replaces colon-delimited text codes with Unicode characters; emoji.demojize() reverses the direction. A third function, emoji.is_emoji(), tests whether a string is an emoji character. From the project's own examples:
>>> import emoji
>>> print(emoji.emojize('Python is :thumbs_up:'))
Python is 👍
>>> print(emoji.demojize('Python is 👍'))
Python is :thumbs_up:
>>> print(emoji.is_emoji("👍"))
TrueText codes follow the colon-delimited format, such as :thumbs_up: and :red_heart:. Spaces in names are replaced with underscores. demojize() converts back to the canonical English name by default, regardless of the language used during emojize(). is_emoji() returns a boolean, which simplifies validation or filtering without parsing the string format manually.
By default, only the official Unicode list is active. Calling emojize() with language='alias' enables the alias list alongside the official codes, adding shorter or colloquial names familiar from chat platforms. Both :thumbsup: (alias) and :thumbs_up: (official) work when language='alias' is set, but only :thumbs_up: works under the default configuration. This distinction is relevant when processing user-submitted text from platforms that use alias names: under the default settings, an unrecognized code passes through unchanged rather than being converted.
pip install emoji and the upgrade flag keeps the Unicode data current
Installing via pip is the standard path:
python -m pip install emoji --upgradeInstalling from the master branch directly requires cloning the repository first:
git clone https://github.com/carpedm20/emoji.git
cd emoji
python -m pip install .Python 3.8 is the minimum version, set in pyproject.toml as requires-python = ">=3.8". Supported Python versions in the classifiers run from 3.8 through 3.14. Both CPython and PyPy are listed as supported implementations.
Including the --upgrade flag matters in practice: the emoji data file is updated when new Unicode emoji are added, and running without it on an older installation leaves unicode_codes/emoji.json at its original version. Newer Unicode emoji will not convert correctly if the package version predates their addition. An example.py file in the example/ directory demonstrates basic usage and can serve as a quick smoke test after install. No explicit guidance on upgrade frequency appears in the project documentation, so reviewing the release history in CHANGES.md before adopting or updating is worthwhile.
Thirteen non-English language codes expand the name tables beyond English
English is the default language parameter ('en'). Passing a different ISO code routes the lookup to a language-specific name table. Supported languages are Spanish ('es'), Portuguese ('pt'), Italian ('it'), French ('fr'), German ('de'), Farsi/Persian ('fa'), Indonesian ('id'), Simplified Chinese ('zh'), Japanese ('ja'), Korean ('ko'), Russian ('ru'), Arabic ('ar') and Turkish ('tr'), covering 13 non-English options.
From the project's examples:
>>> print(emoji.emojize('Python es :pulgar_hacia_arriba:', language='es'))
Python es 👍
>>> print(emoji.demojize('Python es 👍', language='es'))
Python es :pulgar_hacia_arriba:The name :pulgar_hacia_arriba: is the Spanish code for the thumbs-up character. demojize() with language='es' converts the Unicode character back to the Spanish code rather than the English one. Mixing language parameters between emojize() and demojize() calls on the same string requires consistency: encoding with 'es' and then decoding with 'en' returns the English name, not the Spanish one. Applications processing multilingual content need to decide whether to normalize all codes to English or to preserve per-language names through the full pipeline.
Language-specific mappings live in separate JSON files, reflected in pyproject.toml's package data configuration as unicode_codes/emoji_*.json alongside the main unicode_codes/emoji.json.
variant="emoji_type" switches from text presentation to emoji presentation
Some Unicode characters have two presentation forms: a text-style version and an emoji-style version. By default, emojize() renders the text-style version. Passing variant="emoji_type" requests the emoji-style form. From the project's own example:
>>> print(emoji.emojize("Python is fun :red_heart:"))
Python is fun ❤
>>> print(emoji.emojize("Python is fun :red_heart:", variant="emoji_type"))
Python is fun ❤️ #red heart, not black heartWithout the variant argument, output is the text presentation, which some renderers draw as a plain monochrome outline. With variant="emoji_type", the output includes the variation selector character, and terminals or clients that respect it render the character in full color.
This distinction matters most when output goes to a web page, a messaging platform or any context that renders Unicode variation selectors. For plain log files or terminal output where the renderer does not distinguish the two forms, the default behavior is adequate. In an application that generates user-facing messages and needs visual consistency across different display environments, the library controls only which character it emits, not how a given client renders it, so testing output in each target rendering environment is the reliable verification step.
The Unicode data is generated by scraping the Consortium's website, not curated by hand
carpedm20/emoji stores its emoji-to-code mappings in unicode_codes/emoji.json and the language-specific files in unicode_codes/emoji_*.json. These are not manually edited. utils/generate_emoji.py generates them by scraping a table from the Unicode Consortium's website using BeautifulSoup.
That generation step matters for two reasons. First, when the Unicode Consortium publishes new emoji, the package must regenerate the data file and cut a new release before those characters are available in emojize() or demojize(). Second, any error in the scraper or in the upstream table format can introduce incorrect mappings or missing entries. For production use that depends on completeness of the emoji list, the Unicode version in the installed package is the version to verify against requirements.
utils/README.md describes the generation process in more detail. Contributors who want to add new emoji or fix a mapping need to follow that process rather than editing the JSON files directly. A full documentation site at carpedm20.github.io/emoji/docs/ and an overview page listing all emoji the current package version supports are also available.
Alias coverage is not exhaustive and terminal rendering is outside the library's control
emojize() outputs Unicode code points. Whether those code points render as recognizable emoji depends entirely on the terminal, font or client receiving the output. A Python script piping output to a log aggregator, a file or a terminal without emoji font support produces Unicode characters, but the visual representation is outside the library's control. Garbled or box characters in output are a rendering environment problem, not a library bug.
Alias coverage is a separate concern. By default language='alias' is not active, and alias names come from a cheat sheet reference rather than the official Unicode list. Coverage is not exhaustive: a colloquial name familiar from a specific chat platform may not appear in the list until it is added to that reference. Using the default language='en' with official Unicode names avoids that gap, and cross-referencing against the overview page at carpedm20.github.io/emoji/ confirms which codes the installed version actually recognizes.
For use cases where the only requirement is detecting whether a string contains an emoji, Python's standard character property tools can answer that question without adding an external dependency. emoji.is_emoji() is more direct when a simple boolean is the goal, but it pulls in the full library and its bundled data files.
BSD licence in pyproject.toml, GitHub shows Other, and the package ships type information
GitHub classifies the licence as Other. pyproject.toml includes the classifier "License :: OSI Approved :: BSD License", which provides more specificity than GitHub's automated detection. LICENSE.txt at the repository root holds the full text, and reading that file is the required step before redistribution.
Version v2.16.0 was published on 2026-09-16, v2.15.0 on 2025-09-21, and v2.14.1 on 2025-01-16. A push to the master branch was recorded on 2026-09-16. Taehoon Kim and Kevin Wurster are listed as authors in pyproject.toml; Tahir Jalilov is named as maintainer in the README.
Development tooling covers ruff for style checks and pyright, mypy and typeguard for type verification, each with documented install commands. pyproject.toml includes py.typed in the package data, which signals to type checkers that the library ships its own type information. A project that uses type checking already can adopt this library without losing type coverage. CHANGES.md at the repository root is the file to consult before an upgrade, since emoji code names change between versions and those changes can break tests that compare emojize() or demojize() output against expected strings.
Editorial conclusion
Use carpedm20/emoji when a Python application needs to convert between colon-delimited text codes and Unicode characters in either direction, especially when non-English language code lists matter. Skip it when the only requirement is detecting whether a character is an emoji and no external dependency is acceptable. Before adopting, verify that the installed version's Unicode data covers the emoji set your application expects, and read CHANGES.md before any upgrade, since code name changes can break tests that compare emojize() or demojize() output.
Frequently asked questions
How do I install the carpedm20/emoji library?
Run python -m pip install emoji --upgrade. Including --upgrade ensures the emoji Unicode data file is current. Python 3.8 or newer is required, and both CPython and PyPy are supported.
How do I use emoji.emojize() in Python?
Import the library and call emoji.emojize() with a string containing colon-delimited codes such as :thumbs_up:. Pass language='alias' to also accept alias names like :thumbsup: alongside the official Unicode codes.
What languages does carpedm20/emoji support?
English is the default. The project also supports Spanish, Portuguese, Italian, French, German, Farsi/Persian, Indonesian, Simplified Chinese, Japanese, Korean, Russian, Arabic and Turkish, each with its own ISO code string passed to emojize() or demojize().
What is the difference between the official list and alias mode in carpedm20/emoji?
By default only the official Unicode name list is active. Passing language='alias' enables an additional alias list drawn from a cheat sheet reference, allowing shorter colloquial names. The alias list is not exhaustive, so a name from a specific chat platform may not be present.
Does carpedm20/emoji support PyPy?
Yes. pyproject.toml classifiers list PyPy alongside CPython as a supported implementation, with Python 3.8 as the minimum version for both.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/carpedm20-emoji)