Open-source project
andrewgioia/keyrune avatar
andrewgioia/keyrune

Keyrune and the pictographic font for Magic set symbols

Magic: the Gathering set symbol pictographic font

556 stars53 forksLessNOASSERTION

At a glance

What is it?
Keyrune turns the Magic: the Gathering set symbols into a web font, so an application can display an expansion symbol with a single styled span instead of an image, with class names derived from the MTG JSON expansion codes. The interesting parts are the licensing, which is a dual OFL and GPL grant because the symbols are Wizards of the Coast trademarks, and the fact that the whole thing still compiles from LESS with a two-command build.
Who is it for?
Keyrune is a good fit for a Magic application, deck-building site or document generator that needs to show set symbols consistently, because the font approach gives you scalable vectors with no per-set image requests and a class name that matches the expansion code used by MTG JSON.
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 24 days ago.
What is it written in?
Mainly Less, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What Keyrune is and why a font rather than images

Keyrune is described as the first suite of complete Magic: the Gathering expansion and set symbols as a pictographic font. The point of a pictographic font is that a symbol behaves like a letter: you style it with CSS, it scales, it takes the colour of the text around it, and it costs one request for the whole set rather than one image file per expansion.

That last part matters at scale. A deck tool showing card images needs the expansion symbol in the corner of every row, and there are hundreds of expansions. As images that is hundreds of assets, per-format variants, and a request pattern that has to be cached carefully. As a font it is a single woff2 file and the symbols become text nodes.

The class names are the part worth understanding, because it is what ties the font to the rest of your data. The README says the class name codes are based on the expansion codes from MTG JSON, and the usage pattern follows Font Awesome:

html
<link href="css/keyrune.css" rel="stylesheet" type="text/css" />

and a symbol is then an empty element carrying the class, for example `<i class="ss ss-exp"></i>`.

So a symbol is an empty span with a class, and the class encodes which expansion it is. Since the class names come from the same expansion codes that MTG JSON uses in card data, a tool that already stores card records with an expansion code can derive the symbol class directly from the data it has, with no lookup table of its own. That is the design decision that makes Keyrune more than a set of icons, and it is also the constraint to check: if your data uses a different code scheme, the mapping has to be built.

The project is MIT-ish in feel but the licence is not MIT, and we will come back to that, because it is the part most likely to matter commercially.

Getting the font in: source, npm, Bower and jsDelivr

There are several ways to get the stylesheet and the font files into a project, and the README names all of them.

The base instruction is to move the font files to your /fonts directory and include the keyrune.css stylesheet in your head, which is the html line at the top of this section. That works whether you take the files from source, from npm or from Bower.

The CDN route is the newer option. The README announces that you can now include Keyrune via CDN thanks to jsDelivr, and gives the URL to reference for the latest version:

html
<link href="//cdn.jsdelivr.net/npm/keyrune@latest/css/keyrune.css" rel="stylesheet" type="text/css" />

There is a version note attached to that, and it is the kind of detail that breaks a working page. As of v3.1.1 in June 2017 the jsDelivr URL format changed to the form above. jsDelivr still maintains backwards compatibility for everything prior to that, but going forward you should use the new URL.

The old format was the npm package path with a version segment in a different position, and the fact that a CDN path format changed underneath a project and stayed compatible is worth noting for anyone pinning a URL.

The README also points out that you no longer need to explicitly include the font-family via @font-face, since the stylesheet does it, but it gives the ruleset anyway for anyone who wants it, which is useful if you are bundling the fonts yourself rather than loading the stylesheet:

css
@font-face {
  font-family: 'Keyrune';
  src: url('//cdn.jsdelivr.net/npm/keyrune@latest/fonts/keyrune.eot');
  src: url('//cdn.jsdelivr.net/npm/keyrune@latest/fonts/keyrune.eot?#iefix') format('embedded-opentype'),
    url('//cdn.jsdelivr.net/npm/keyrune@latest/fonts/keyrune.woff2') format('woff2'),
    url('//cdn.jsdelivr.net/npm/keyrune@latest/fonts/keyrune.woff') format('woff'),
    url('//cdn.jsdelivr.net/npm/keyrune@latest/fonts/keyrune.ttf') format('truetype'),
    url('//cdn.jsdelivr.net/npm/keyrune@latest/fonts/keyrune.svg') format('svg');
  font-weight: normal;
  font-style: normal;
}

The format list is the full set from embedded OpenType through woff2, woff, truetype and svg, which is a sign of a project that has been maintained across a long period and has had to serve every browser generation that came along.

The build: two LESS commands and a publish script

The source is editable and the README invites it, saying you can feel free to edit the source files and compile Keyrune to fit your needs, and that both LESS and Sass are supported.

The package.json shows how the LESS path works. There are two compile targets, one producing the readable stylesheet and one producing a minified one:

json
    "less": "lessc less/keyrune.less css/keyrune.css",
    "lessmin": "lessc --clean-css less/keyrune.less css/keyrune.min.css",

The build script then copies the fonts and the minified stylesheet into the docs directory so the documentation site is self-contained, and the publish script chains the whole sequence: less, lessmin, rename, build.

The rename step is the one that deserves an explanation, because it is a workaround rather than an obvious necessity. It loops over the fonts directory and lowercases any filename that contains uppercase characters, moving it to the lowercase version. That is a response to a class of real problem: case-insensitive filesystems on macOS and Windows will happily serve a file requested as Keyrune.ttf from a directory where the file is actually keyrune.ttf, and on a case-sensitive Linux server that request 404s. Normalising the filenames at publish time means the same URL works everywhere.

The devDependencies are minimal and specific: clean-css, which provides the minifier that lessc uses, lessc itself, and zepto. The engines field says node with no version constraint, and the package declares no runtime dependencies, which is right for a stylesheet and a set of font files.

The repository layout follows from that. There is a less/ directory with the source, a css/ directory with the compiled output, a fonts/ directory, an svg/ directory with the vector sources, a docs/ directory for the documentation site, and a contributing/ directory for the process of adding a new set.

Using Keyrune outside the browser

The font is not only for web pages, and the README documents the desktop path in a way that is worth repeating because it addresses a real confusion.

To copy Keyrune symbols into desktop software, or to access the vectors directly, you go to the cheatsheet on the documentation site, copy the character rather than the unicode representation, and paste it into your desktop application after installing keyrune.ttf.

That instruction is precise in a way that matters. The character and the unicode representation are not the same thing: the font maps a private-use codepoint to a glyph, and what you copy from a browser is the character, which is meaningless as text and only renders correctly in an application that has keyrune.ttf installed. Copying the unicode codepoint instead gives you a character that displays as a missing glyph box, which is a confusing failure if you do not know the difference.

The cheatsheet serves double duty. It is a reference for which character belongs to which set, and it is the mechanism for getting that character onto the clipboard.

There is also a linked sample Word document with step-by-step instructions for people who want the desktop route explained in more detail, and the documentation site is where both of those live.

The practical upshot is that the font works in a desktop application as long as the application can use an installed font, which covers Word, PowerPoint and most rich text editors. It does not work for a plain text file, and it does not work in an application that blocks custom fonts, and neither of those limitations is stated in the documentation because they are properties of the host application rather than of Keyrune.

The licence, and the trademark question underneath it

This is the part of the project that deserves careful reading, and the README is upfront about it.

All set symbol images are trademarks of Wizards of the Coast, and the README points to LICENSE.md for a complete description of the licences that Keyrune is distributed under. It also says that public attribution is greatly appreciated but not required.

The package.json licence field is (OFL-1.1 AND GPL-3.0-only), which is a dual grant: the Open Font License covers the font itself, and the GPL covers the rest, and the AND means both apply. The OFL is the standard licence for a font, and its requirements are mainly that the font is not sold on its own and that any derivative font keeps the same licence. The combination with GPL is what makes the project license field show as a custom licence that GitHub cannot classify.

But the trademark point is the one that matters more than either, and it is separate from the copyright licence. The symbols are Wizards of the Coast trademarks, and a trademark is a different kind of right from a copyright: it governs use of the mark in commerce, and it does not expire the way a copyright does. The README does not spell out what the LICENSE.md file says about the boundaries, and it is worth reading that file directly rather than inferring from the package.json field, because a font that renders trademarked symbols is a slightly unusual licence situation and the practical questions, such as whether an unaffiliated site can use it commercially, are answered in that document.

The other practical note is that attribution is not required, which matters for anyone who was expecting a visible credit to be compulsory. It is not.

The release history is regular and tracks new sets. v3.19.0 covers the Secrets of Strixhaven and Summer 2026 sets, v3.18.0 was Lorwyn Eclipsed, and v3.17.0 was Edge of Eternities. The last push was on 2026-09-29, so a new expansion release is the normal reason for a version bump.

Where Keyrune is the wrong choice

Three limits are worth stating plainly.

The first is scope. The font contains Magic expansion symbols and nothing else. If you need card symbols from other trading card games, or a general-purpose icon set, this is not the project, and there is no plugin mechanism to extend it with other symbol families.

The second is the class naming contract. Because the class names are derived from the expansion codes in MTG JSON, the font is coupled to a particular external data standard. If your card data comes from another source, or from a hand-maintained collection, you have to build and maintain the mapping from your codes to the ss- class names yourself, and the failure mode is silent. A wrong class name renders an empty box, not an error, and a box the size of a symbol is easy to miss in a dense list.

The third is the licence, discussed above, and it is a real constraint for a commercial project. The font is free to use, the symbols are trademarks, and the precise terms live in a file rather than in the README. A commercial site showing set symbols in its own card list is a different position from a personal blog showing them, and the README does not draw that line for you.

There is also a project-level point. The README is thin, deliberately so, because the documentation has moved to a separate site at keyrune.andrewgioia.com, and the changelog and todo items moved to CHANGELOG.md. That is a reasonable choice for a project of this size, and it does mean that the repository readme is an index rather than a manual. The contributing/ directory in the tree is where the process for adding a set lives, which is the piece most people would want if they wanted to contribute an expansion that has not been added yet.

Editorial conclusion

Keyrune is a good fit for a Magic application, deck-building site or document generator that needs to show set symbols consistently, because the font approach gives you scalable vectors with no per-set image requests and a class name that matches the expansion code used by MTG JSON. It is a poor fit if you need symbols for a game other than Magic, since the entire font is expansion symbols, and a poor fit if you need to redistribute the font inside a product you sell without reading LICENSE.md, because the symbols are Wizards of the Coast trademarks and the repository ships a custom licence rather than a plain open source one. Before adopting, read LICENSE.md rather than relying on the package.json licence field, and check that your card data source uses the same expansion codes the class names are derived from, since a mismatch there produces silently wrong symbols rather than an error.

Frequently asked questions

What is Keyrune and what does it provide?

Keyrune is a pictographic font of complete Magic: the Gathering expansion and set symbols, described as the first suite of its kind. Symbols are displayed with Font Awesome style elements such as `<i class="ss ss-exp"></i>`, and the class name codes are based on the expansion codes from MTG JSON.

How do I include Keyrune in a web page?

Move the font files to your /fonts directory and include the stylesheet with `<link href="css/keyrune.css" rel="stylesheet" type="text/css" />`, or load it from jsDelivr with `<link href="//cdn.jsdelivr.net/npm/keyrune@latest/css/keyrune.css" rel="stylesheet" type="text/css" />`. The jsDelivr URL format changed in v3.1.1 in June 2017, though older formats still work.

How do I use Keyrune symbols in a desktop application?

Copy the character from the cheatsheet on the documentation site rather than the unicode representation, then paste it into the application after installing keyrune.ttf. The README links a sample Word document with step-by-step instructions.

Can I rebuild Keyrune from source?

Yes. The source files are editable and both LESS and Sass are supported. The LESS path compiles with lessc to css/keyrune.css and css/keyrune.min.css, and the publish script runs the compile, a filename lowercasing step, and the documentation build in sequence.

What licence is Keyrune distributed under?

The package.json declares (OFL-1.1 AND GPL-3.0-only), and the README notes that all set symbol images are trademarks of Wizards of the Coast. The complete licence terms are in LICENSE.md, and public attribution is appreciated but not required.

Official sources

  1. andrewgioia/keyrune on GitHub
  2. Issues
  3. README
  4. Releases
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/andrewgioia-keyrune.svg)](https://hysenlabs.com/projects/andrewgioia-keyrune)

Was this useful?