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

@quillmark/fonts

v0.2.1

Published

The font suite every Quillmark client hands its engine: openly licensed families a stored document can name and find again.

Readme

@quillmark/fonts

The font suite every Quillmark client hands its engine: openly licensed families a stored document can name and find again in any client that loads the suite.

| Family | Role | | ---------------- | --------------------------------------------- | | TeXGyreTermes | Times New Roman metrics, shown as "Termes" | | Arimo | Arial and Helvetica metrics | | Cousine | Courier New metrics | | Caladea | Cambria metrics | | Gelasio | Georgia metrics | | Libertinus Serif | Typst's default text face | | Cinzel | inscriptional capitals | | DejaVu Sans | wide humanist sans | | Inter | screen-first UI sans | | JetBrains Mono | code monospace | | TeXGyreSchola | Century Schoolbook metrics, shown as "Schola" |

Each in regular, italic, bold and bold italic (Cinzel, drawn in capitals, in regular and bold), subset to Latin, about 2.6 MB in all. A character outside the subset falls back to the surrounding font.

Install

npm install @quillmark/fonts @quillmark/wasm

Building an engine over the suite

import { loadSuite } from '@quillmark/fonts';
import { Engine } from '@quillmark/wasm';

const engine = new Engine({ fonts: await loadSuite() });

loadSuite() answers every face's file, as fonts takes them. The main entry fetches each one beside the module through new URL(file, import.meta.url), which Vite and webpack 5 emit as a hashed asset with no plugin; under Node, import it from @quillmark/fonts/node, which reads the same files off disk. Vite's dev server pre-bundles dependencies away from the files beside them, so exclude the package there, as @quillmark/wasm is excluded:

export default defineConfig({ optimizeDeps: { exclude: ['@quillmark/wasm', '@quillmark/fonts'] } });

The engine reads its library when it first loads a Typst backend, so the suite is on the path to the first page. Start loadSuite() at boot, beside init() and the quiver, rather than when the first page is asked for. Serve the files with brotli: the engine reads TTF and OTF only, so there is no WOFF2 to fall back on.

A host's own fonts go after the suite:

const engine = new Engine({ fonts: [...(await loadSuite()), ...extras] });

A third-party client opening the same documents does not have those, and a run set in one falls back with a warning there. The suite is the only portable promise.

The editor

@quillmark/svelte's VisualEditor takes the faces the engine lists, which are the suite's bytes, so one download serves both sides. LABELS is the name its picker shows for a family whose own name reads badly; the mark saves the family:

<script lang="ts">
	import { LABELS } from '@quillmark/fonts';

	let fonts = $state<FontFace[]>([]);
	engine.fontFaces(quill).then((faces) => (fonts = faces));
</script>

<VisualEditor {doc} {quill} {fonts} fontLabels={LABELS} />

Rendering with the CLI

quillmark render takes the same library through --font, once a file. Pass this package's files to render a document as a browser client does:

quillmark render ./my-quill doc.md $(for f in node_modules/@quillmark/fonts/files/*.[ot]tf; do echo --font "$f"; done)

What a version promises

A family name is a promise to every document that sets text in it, so a family is removed or renamed, and a face's file changed, only in a breaking version: a major one, or a minor one while the major is 0. New metrics can reflow a stored document. A new family is a minor version, or a patch while the major is 0. FAMILIES names the suite's families, LABELS the display names, which can change in any version, and manifest.json (importable as @quillmark/fonts/manifest.json) each face's weight, style, file and sha256.

Licences and provenance

The package's code is Apache-2.0. Every font file is a subset of an upstream release, its licence text beside it as files/<Family>-<Licence>.txt: the SIL Open Font License 1.1 for eight families, the GUST Font License (LPPL 1.3c) for TeXGyreTermes and TeXGyreSchola, and the Bitstream Vera licence for DejaVu Sans. Each lets a subset keep its family's name. The names are trademarks of their holders, used here to name their fonts.

manifest.json records each family's upstream source, a repository at a commit or a release archive, and each face's upstream file and its sha256. Each file was cut from that upstream file with fontTools 4.68.0, DejaVu Sans's regular face with --drop-tables+=MATH as well:

pyftsubset <upstream file> \
  --unicodes="U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD" \
  --layout-features='*' --name-IDs='*' --name-languages='*' --notdef-outline

The design, the rules and what was left out are in FONTS.md.