npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

remark-madoka-runes

v0.3.1

Published

remark plugin to render text in Puella Magi Madoka Magica Witch Runes (魔女文字) using the archaic, modern, musical and Latin rune fonts

Readme

remark-madoka-runes

A remark plugin that renders text in Puella Magi Madoka Magica Witch Runes (魔女文字).

It handles all four rune alphabets (archaic, modern, musical and Latin), and the fonts come with it.

Install

pnpm add remark-madoka-runes remark-directive

remark-directive powers the default syntax, so put it in your pipeline first. If you are not using it, see plain CommonMark below.

Use

:runes[HOMULILLY]
:runes[Oktavia von Seckendorff]{variant=musical}
:runes[Yaginokonoyume]{.latin}

:::runes{variant=archaic}
A block of rune text.
:::
import rehypeStringify from "rehype-stringify";
import remarkDirective from "remark-directive";
import remarkMadokaRunes from "remark-madoka-runes";
import remarkParse from "remark-parse";
import remarkRehype from "remark-rehype";
import { unified } from "unified";

const file = await unified()
  .use(remarkParse)
  .use(remarkDirective)
  .use(remarkMadokaRunes)
  .use(remarkRehype)
  .use(rehypeStringify)
  .process(":runes[HOMULILLY]");

:runes[HOMULILLY] becomes:

<span class="madoka-runes madoka-runes--default" data-rune-variant="default">HOMULILLY</span>

Load the stylesheet once somewhere in your app. It sets up the @font-face rules and points them at the bundled fonts:

import "remark-madoka-runes/style.css";
@import "remark-madoka-runes/style.css";

The HTML still holds ordinary Latin letters, so the text copies, searches and reads aloud like anything else. Only the font makes it look like runes.

The stylesheet sets the font and nothing else. Size, line height and colour are yours to set on .madoka-runes.

Plugin order

Put this plugin after remark-directive and before anything that rewrites directives it does not recognise. Plugins built on the Astro Starlight admonitions pattern turn every unhandled directive back into plain text, so a :runes[...] they reach first is gone before this plugin runs:

remarkPlugins: [remarkDirective, remarkMadokaRunes, remarkAdmonitions]

Once this plugin has handled a directive it replaces the node outright, so sweepers running later leave it alone.

Variants

| Variant | Font | Case applied | | --- | --- | --- | | default | MadokaRunes | none | | archaic | MadokaRunes | uppercase | | modern | MadokaRunes | lowercase | | musical | MadokaMusical | none | | latin | MajoPMMM | uppercase |

MadokaRunes packs two alphabets into one font: archaic on the uppercase letters, modern on the lowercase ones. So archaic and modern just change the case of your text, and default leaves it alone, which means mixed-case text comes out as a mix of the two.

Pick a variant with {variant=musical} or the shorthand {.musical}.

The alphabets have gaps. The musical font is missing J, Q, W and X, and the Latin font only covers ASCII. Anything with no rune falls back to whatever font surrounds it, and the plugin leaves a warning on the vfile when that happens.

Plain CommonMark

If you are not using remark-directive, turn on the commonmark syntax instead. It uses a fenced code block for a run of runes and an inline code span for a few words, both of which are ordinary CommonMark that any parser already understands.

.use(remarkMadokaRunes, { syntax: ["commonmark"] })
```runes-archaic
Kriemhild Gretchen
```

Her name is `runes:HOMULILLY`, and hers is `runes-latin:Yaginokonoyume`.

The variant goes in the info string or the prefix (runes-musical), and a bare runes uses the default. Anything else in a code block or code span is left alone. Pass syntax: ["directive", "commonmark"] to accept both.

Directives are the default because they are the established way to add syntax to markdown, and because a code fence carries no attributes and cannot nest other markdown. Reach for CommonMark when directives are not already in your setup.

Options

| Option | Type | Default | Description | | --- | --- | --- | --- | | syntax | Syntax[] | ["directive"] | Which syntaxes to accept: "directive", "commonmark", or both. | | name | string | "runes" | Directive name, fence info string and inline code prefix. | | variant | RuneVariant | "default" | Variant to use when a directive does not name one. | | className | string | "madoka-runes" | Base class; the variant is appended as <className>--<variant>. | | tagName | string | "span" | Element for inline runes. | | blockTagName | string | "div" | Element for block runes. | | inlineStyle | boolean | false | Also emit style="font-family:..." on each element. | | inlineFonts | boolean | false | Embed the fonts as data: URI @font-face rules. Node only. | | title | boolean | false | Add title with the original, untransformed text. | | checkGlyphCoverage | boolean | true | Warn when text contains characters the font has no glyph for. |

Self-contained output

With inlineFonts: true the plugin puts a <style> block at the top of the document with the fonts baked in as base64 WOFF2, and only the fonts that document actually uses. You then need no stylesheet and no font files, but every font adds 6 to 36 KB to each document.

.use(remarkMadokaRunes, { inlineFonts: true })

Warnings

Everything below is reported as a vfile message rather than an error, so none of it breaks your build:

| ruleId | When | | --- | --- | | missing-glyph | The text uses a character the chosen font has no rune for. | | unknown-variant | A variant name that does not exist was asked for. | | missing-remark-directive | The file uses :runes[...] but remark-directive is not in the pipeline, so it would silently stay plain text. |

const file = await processor.process(":runes[JQWX]{variant=musical}");
console.log(file.messages.map(String));
// The musical rune font (MadokaMusical) has no glyph for "J", "Q", "W", "X"; ...

Example

Run pnpm run build, then node example/build-demo.mjs. It writes example/demo.html, one self-contained page showing all five variants.

Fonts

pnpm run build:fonts rebuilds the WOFF2 files and the glyph coverage tables from the TTFs.

The Witch Runes were designed by Inu Curry for Puella Magi Madoka Magica (© Magica Quartet / Aniplex・Madoka Partners・MBS). The fonts are fan-made and the MIT license does not cover them, so read assets/fonts/NOTICE.md first, especially if this is for commercial work. This is an unofficial fan project.

The fonts and the rune tables come from the Puella Magi Wiki.

License

MIT for the code. This project also bundles copyrighted fonts that are not under the MIT license. Read assets/fonts/NOTICE.md before using them.