Skip to content

Emoji: Add the Twemoji COLRv1 font and its reproducible build - #13618

Open
Jiwoon-Kim wants to merge 2 commits into
WordPress:trunkfrom
Jiwoon-Kim:add/66144-twemoji-colrv1-font
Open

Jiwoon-Kim wants to merge 2 commits into
WordPress:trunkfrom
Jiwoon-Kim:add/66144-twemoji-colrv1-font

Conversation

@Jiwoon-Kim

@Jiwoon-Kim Jiwoon-Kim commented Sep 19, 2026

Copy link
Copy Markdown

This adds Twemoji 17.0.3 as one COLRv1 color font and a flags-only subset of it, with the tooling that builds them, as the first step of #66144. Nothing loads the fonts yet: there is no @font-face and no change in behavior. Using it for the emoji a browser cannot draw, and handing off to the image fallback, is follow-up work that depends on the design discussion in the ticket.

  • src/wp-includes/fonts/twemoji/twemoji-colrv1.woff2: 657,364 bytes, SHA-256 0e8645e0fcbb7c98b18eeaa099122633a9129823336f6a76a944a31be07a4700.
  • src/wp-includes/fonts/twemoji/twemoji-colrv1-flags.woff2: 108,888 bytes, SHA-256 108cd5e892d9ca9cab788b573115d9662b4aa6fa24b48520cf4b792951fee649. It is cut from the full font with the fontTools subsetter and covers country, subdivision, rainbow, transgender and pirate flags: for browsers that draw other emoji but not flags, such as Chromium on Windows, it is about a sixth of the full font.
  • Next to them: manifest.json (Twemoji commit and hashes, tool versions, output hashes, coverage counts), source.txt, LICENSE-GRAPHICS and aliases.txt.
  • tools/emoji/: the build script, a Dockerfile with the base image pinned by digest, and requirements.lock pinning every Python package. See tools/emoji/README.md.

The font is built by maintainers when Twemoji is updated; sites only serve the file. The build downloads the Twemoji release by commit, checks the archive and SVG-set hashes, builds with nanoemoji, writes the CC-BY 4.0 attribution into the font's name table, and with --verify rebuilds and requires byte-identical output. It normalizes its input in two recorded ways: aliases for spellings without FE0F, which Edge needed to render every fully-qualified sequence as one glyph, and a square viewBox for the watermelon (1f349.svg), reported upstream in jdecked/twemoji#133. tools/emoji/README.md has the details.

In Edge 153 on Windows, all 3,944 fully-qualified RGI sequences in Emoji 17.0 render as one glyph in the font's colors, and every sequence in the flag profile does with the flags subset (265 fully-qualified). manifest.json records those results against each font's SHA-256. The research behind this, including the browser check, is at https://github.com/Jiwoon-Kim/axismundi/tree/c690d2e/research/twemoji-colrv1.

Points for review:

  • License. The Twemoji graphics are CC-BY 4.0, and this would put them in Core's tree; the only CC-licensed assets I found in Core today are CC0 images in bundled themes. The attribution is in the font's name table, LICENSE-GRAPHICS and source.txt. Is that enough, or should license.txt or the credits mention it?
  • Location. The font and its records are in wp-includes/fonts/twemoji/, next to Dashicons, so they ship with every install; aliases.txt and manifest.json add 40 KB of text. They could live under tools/emoji/ instead, with only the font and its attribution in wp-includes.
  • Reproducibility. docker run … --verify rebuilds from the pinned inputs and compares bytes; it takes about 20 minutes. It passed in this branch's layout for both fonts.
  • The binaries. Each WOFF2's SHA-256 is in manifest.json, so a rebuild can be checked against the committed files.

Trac ticket: https://core.trac.wordpress.org/ticket/66144
Related: https://core.trac.wordpress.org/ticket/44001

Use of AI Tools

  • AI assistance: Yes
  • Tool(s): Claude Code, Codex
  • Model(s): Claude Opus 5 (Claude Code)
  • Used for: the build script, the Docker setup, the browser checks and this description. I reviewed the changes, the measurements and the output.

This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.

🤖 Generated with Claude Code

Adds Twemoji 17.0.3 as one COLRv1 color font in
`wp-includes/fonts/twemoji/`, with a manifest of its inputs and outputs,
its CC-BY 4.0 attribution and the list of aliases it adds, and the
tooling in `tools/emoji/` that builds it from a pinned Twemoji release in
a pinned Docker image. `--verify` rebuilds and requires byte-identical
output.

Nothing loads the font yet; using it as the emoji fallback is follow-up
work.

See #66144.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

Test using WordPress Playground

The changes in this pull request can previewed and tested using a WordPress Playground instance.

WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser.

Some things to be aware of

  • All changes will be lost when closing a tab with a Playground instance.
  • All changes will be lost when refreshing the page.
  • A fresh instance is created each time the link below is clicked.
  • Every time this pull request is updated, a new ZIP file containing all changes is created. If changes are not reflected in the Playground instance,
    it's possible that the most recent build failed, or has not completed. Check the list of workflow runs to be sure.

For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation.

Test this pull request with WordPress Playground.

@Jiwoon-Kim

Copy link
Copy Markdown
Author

The five PHPUnit matrix failures all time out in Build WordPress after Grunt reports Done.; PHPUnit does not start. The same timeout appears in recent trunk runs 35335345549 and 35304568318. The build step completed normally in the other matrix jobs.

@Jiwoon-Kim
Jiwoon-Kim marked this pull request as ready for review September 19, 2026 16:09
@github-actions

Copy link
Copy Markdown

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

Core Committers: Use this line as a base for the props when committing in SVN:

Props kimjiwoon.

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

Adds `twemoji-colrv1-flags.woff2`, cut from the full font with the
fontTools subsetter: country, subdivision, rainbow, transgender and
pirate flags, 108,888 bytes against 657,364 for the full font. It is for
browsers that draw other emoji but not flags.

The build declares subsets in a `SUBSETS` registry and records each one's
code points, hash and coverage in `manifest.json`. Browser results are
recorded in `sources.json` per output SHA-256 and copied into the
manifest only for matching outputs. The full font is unchanged.

See #66144.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant