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

fontdone

v2.14.3

Published

Pure-Rust font loading and rasterization for browsers and Node.js through WebAssembly

Readme

fontdone

Latest release: 2.14.3-alpha.12.

fontdone is the JavaScript npm package for the pure-Rust fontdone engine. It ships a prebuilt wasm32-unknown-unknown module and a zero-dependency ESM wrapper for opening font bytes and rasterizing individual glyphs.

The documented JavaScript API follows SemVer. This package is not a complete FreeType replacement or a text-shaping or layout engine.

Install

npm install [email protected]

Node.js

Save as render.mjs. Run node render.mjs /path/to/your-font.ttf with a font you are licensed to use. Requires Node.js 20 or newer.

import { readFile } from "node:fs/promises";
import createFontdone from "fontdone";

const fontBytes = await readFile(process.argv[2]);
const engine = await createFontdone();
try {
  const face = engine.openFace(fontBytes, { pixelSize: 32 });
  try {
    const bitmap = face.render("A");
    console.log(bitmap.width, bitmap.height, bitmap.pixels.length);
  } finally {
    face.close();
  }
} finally {
  engine.close();
}

Browser

Serve your licensed font at /fonts/example.ttf or change the URL to your own asset. The package loads its bundled WASM module automatically.

import createFontdone from "fontdone";

const [engine, fontBytes] = await Promise.all([
  createFontdone(),
  fetch("/fonts/example.ttf").then((response) => response.arrayBuffer()),
]);
const face = engine.openFace(fontBytes, { pixelSize: 32 });

try {
  const bitmap = face.render("A");
  console.log(bitmap.width, bitmap.height, bitmap.pitch, bitmap.pixels);
} finally {
  face.close();
  engine.close();
}

In browsers, the default initializer fetches fontdone.wasm relative to the ESM entry point. In Node.js, the package's conditional node export reads the same bundled asset from disk, so createFontdone() works without a fetch(file://…) call. Pass an explicit URL, Response, ArrayBuffer, typed-array view, WebAssembly.Module, or WebAssembly.Instance when your asset pipeline needs different loading behavior:

const engine = await createFontdone("/assets/fontdone.wasm");

The loader uses streaming instantiation when available and falls back to an ArrayBuffer when the server does not send application/wasm.

Runtime contract

The maintained package requires ESM, WebAssembly, and WebAssembly JavaScript BigInt integration. Browser initialization requires fetch; Node.js uses its conditional entrypoint and the local bundled asset. The wrapper performs no font or telemetry requests; the only implicit asset load is its own Wasm module.

Each initializer call owns a separate WebAssembly instance. Faces and memory offsets are instance-local and cannot be transferred to another instance or Worker. Create one engine per Worker and close every face deterministically.

render maps one Unicode scalar, loads the glyph, renders it in normal grayscale mode, and copies the result out of linear memory. Its result has:

  • glyphIndex: the mapped glyph index;
  • width and height: bitmap dimensions in pixels;
  • pitch: signed bytes per source row;
  • pixels: an owned Uint8Array of abs(pitch) * height bytes.

The package does not shape text, apply bidi ordering, choose fallback fonts, or retain the caller's font buffer. Use a shaping library before loading glyph indices when those behaviors are required.

API

  • createFontdone(source?) / init(source?): create an independent engine.
  • engine.openFace(bytes, { faceIndex?, pixelSize? }): copy bytes, open a face, and select an integer pixels-per-EM size (16 by default).
  • face.setPixelSize(size) or setPixelSizes(width, height): select integer pixels per EM.
  • face.getCharIndex(character): map one number or one Unicode scalar string.
  • face.loadGlyph(index, loadFlags?): load an explicit glyph.
  • face.renderGlyph(renderMode?): render and copy the current glyph bitmap.
  • face.render(character, options?): map, load, and render in one call.
  • face.close() / engine.close(): deterministic, idempotent wrapper cleanup.

Nonzero engine statuses throw FontdoneError, whose code is the preserved FreeType-compatible FT_Error value and whose operation names the failed wrapper call. Programmer errors such as an invalid size or use after close throw standard JavaScript errors.

TypeScript declarations ship with the package. The complete low-level export and record inventory is also distributed as abi.json; only the wrapper above is promoted as the JavaScript application API.

Security and license

Fonts are untrusted binary input and can demand substantial CPU or memory even inside WebAssembly. Apply application-level input-size and execution limits. Report vulnerabilities through the repository's private security-advisory route.

The package is distributed under the FreeType License (FTL). See FTL.TXT and NOTICE.md for terms and attribution.