crystal-emojis
= crystal-emojis :toc: macro :toclevels: 2
Emoji rendering for Crystal — embedded curated set of ~200 SVGs from https://github.com/jdecked/twemoji[Twemoji], plus an opt-in on-disk cache for the rest of the catalogue (~4000 SVGs, ~18 MB). Pure Crystal, no runtime dependency for the curated set.
🇫🇷 Lisez ce document en français : link:README.fr.adoc[README.fr.adoc]
toc::[]
== Migration from crystal-emojis-lite v0.1
The shard was renamed from crystal-emojis-lite to crystal-emojis in v0.2. To migrate :
[source,yaml]
Before (v0.1)
dependencies: crystal-emojis-lite: github: aloli-crystal/crystal-emojis-lite
After (v0.2)
dependencies: crystal-emojis: github: aloli-crystal/crystal-emojis version: "~> 0.2"
The Crystal API is unchanged (module name CrystalEmojis). crystal-emojis-full has been merged into this single shard (via the cache mechanism) and is going to be deleted.
== How it works
Two-layer lookup :
. Embedded curated set : ~208 emojis baked into your binary at compile time (~840 KB). Covers the 90 % case of technical documentation : status, colours, dev tools, common faces. . On-disk cache : the rest of the Twemoji catalogue, downloaded on demand and stored under $XDG_CACHE_HOME/crystal-emojis/svg/. Empty by default — you (or your downstream tool) populate it.
This way every consumer pays only for what they need : the curated set is always there, the long tail (~3800 extra SVGs) only ships when explicitly requested.
== Installation
[source,yaml]
dependencies: crystal-emojis: github: aloli-crystal/crystal-emojis version: "~> 0.2"
== API (use from your Crystal application)
[source,crystal]
require "crystal-emojis"
=== Lookup ===
Pulls from the embedded set first, then from the on-disk cache.
CrystalEmojis.svg('✅') # => "<svg ...>" CrystalEmojis.svg(0x2705) # => same CrystalEmojis.svg('🦄') # => nil if cache empty, "<svg ...>" once cached
Multi-codepoint sequences (ZWJ joins, skin tones, regional flags)
are typically only available from the cache.
CrystalEmojis.svg([0x1F468, 0x200D, 0x1F4BB]) # 👨💻
=== Cache management (programmatic) ===
Trigger the download from your own application — no CLI needed.
CrystalEmojis::Cache.pull
=> downloads ~4000 SVG into the user-level cache, returns the count
Override the source — point at your private mirror.
CrystalEmojis::Cache.pull(source: "https://nas.aloli.local/twemoji/svg")
Write to the system-wide cache (needs root, useful for FreeBSD
servers provisioned via crystal-beryl, etc.).
CrystalEmojis::Cache.pull(system: true)
Inspection
CrystalEmojis::Cache.dir # => "/Users/.../Library/Caches/crystal-emojis/svg" CrystalEmojis::Cache.size # => 0 initially, ~4001 after pull CrystalEmojis::Cache.populated? # => false then true
Pre-flight check before processing a document — if the cache
isn't populated yet, decide what to do (warn the user, trigger
.pull, or just gracefully fall back to text).
unless CrystalEmojis::Cache.populated? puts "Run crystal-emojis pull for full emoji coverage." end
== CLI
[source,shell]
Build the binary once.
shards build --release crystal-emojis
Populate the user cache with the full Twemoji catalogue.
crystal-emojis pull
Téléchargement vers : /Users/.../Library/Caches/crystal-emojis/svg
Source : https://raw.githubusercontent.com/jdecked/twemoji/main/assets/svg
Patientez (≈ 4000 SVG, ~18 Mo)...
Téléchargé : 4001 nouveau(x) SVG (cache total : 4001)
Use a custom mirror.
crystal-emojis pull --source https://your.mirror/twemoji/svg
System-wide cache (multi-user setups).
crystal-emojis pull --system
Inspection.
crystal-emojis info
Emplacement : /Users/.../Library/Caches/crystal-emojis/svg
Taille : 4001 SVG
Embarqués : 208 (curated set)
Wipe the cache.
crystal-emojis purge
=== Custom mirror requirements
The pull command auto-discovers the list of available codepoints in two ways :
. MANIFEST.txt at <source>/MANIFEST.txt — one codepoint key per line, lowercase hex, multi-codepoint sequences joined with -. Comments (#) and blank lines ignored. This is the recommended interface for private mirrors. . GitHub API fallback — works for the upstream Twemoji repo only.
So a private mirror just needs to host <key>.svg files plus a MANIFEST.txt listing them. A 2-line nginx static server is enough.
=== Cache location
[cols="1,3"] |=== | OS / mode | Default path
| macOS (user) | ~/Library/Caches/crystal-emojis/svg/
| Linux/FreeBSD (user) | $XDG_CACHE_HOME/crystal-emojis/svg/ (default ~/.cache/crystal-emojis/svg/)
| Any (system-wide via --system) | /var/cache/crystal-emojis/svg/
| Any (override) | $CRYSTAL_EMOJIS_CACHE_DIR env var |===
== Attribution
Twemoji © Twitter, Inc and other contributors. CC-BY 4.0 — see data/svg/LICENSE-twemoji.txt for the full text.
Required attribution when redistributing :
[source]
Graphics: Twemoji, © Twitter, Inc, CC-BY 4.0 https://github.com/jdecked/twemoji
== Licence summary
- Crystal code : MIT, see link:LICENSE[LICENSE]
- Embedded SVG graphics : Twemoji CC-BY 4.0
- Cached SVG graphics : same Twemoji CC-BY 4.0 (downloaded on demand)
== Development
[source,shell]
shards install crystal spec bin/ameba crystal tool format src/ spec/
crystal-emojis
- 0
- 0
- 0
- 1
- 1
- about 6 hours ago
- April 25, 2026
MIT License
Sun, 26 Apr 2026 07:41:19 GMT