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

fontproof

v2.6.0

Published

Accessible, dependency-free type tester for the web — a vanilla JS core with an optional React wrapper. Composable OpenType features, variable-font axes, and auto-fit sizing.

Readme

FontProof

npm CI

▶ Live demo

A micro toolbar for testing type on the web — a compact bar of controls over a live, editable sample. Accessible and dependency-free: adjust size, tracking, weight, italic, alignment, line-wrap, and composable OpenType features live. Ships a framework-agnostic vanilla core and an optional React component.

Formerly published as type-tester-tdf (and briefly typebar-tdf); renamed to FontProof to reflect what it really is — a focused type-proofing toolbar: a compact bar of controls over a live sample.

v2 is a ground-up rewrite. The legacy jQuery + jQuery UI + BigText widget (v1) is preserved at the v1.0.0 git tag. v2 has no runtime dependencies, builds accessible native controls, escapes all input (no eval, no innerHTML), composes multiple OpenType features at once, and auto-fits with ResizeObserver. See Migrating from v1.

Install

npm install fontproof

Import the stylesheet once (optional — the component works without it):

import "fontproof/styles.css";

Vanilla JS

Programmatic

import { FontProof } from "fontproof";
import "fontproof/styles.css";

const tester = new FontProof(document.querySelector("#demo"), {
  text: "Typography",
  fontFamily: "Inter",
  size: 96,
  controls: { size: true, tracking: true, weight: true, italic: true, features: true },
});

// later…
tester.destroy();

Declarative (data-* auto-init)

<div
  data-fontproof
  data-font="Inter"
  data-size="96"
  data-text="Typography"
  data-controls="size,tracking,weight,italic,align,features"
></div>

<script type="module">
  import { autoInit } from "fontproof";
  import "fontproof/styles.css";
  autoInit(); // initialises every [data-fontproof] element
</script>

autoInit() is idempotent — already-initialised elements are skipped.

React

import { FontProofComponent } from "fontproof/react";
import "fontproof/styles.css";

export function Demo() {
  return (
    <FontProofComponent
      text="Typography"
      fontFamily="Inter"
      size={96}
      controls={{ size: true, weight: true, features: true }}
      onChange={(state) => console.log(state)}
    />
  );
}

React is a peer dependency (>=17); the core stays dependency-free.

Options

new FontProof(host, options) / <FontProofComponent {...options} />:

| Option | Type | Default | Description | | --- | --- | --- | --- | | text | string | "" | Initial sample text. | | fontFamily | string | — | Primary family to test. | | fallback | string | "sans-serif" | Fallback stack appended after the family. | | size | number \| "fit" | 80 | Px size, or "fit" to auto-fit the container. | | tracking | number | 0 | Letter-spacing in em. | | weight | number | 400 | Font weight (or variable wght axis). | | italic | boolean | false | Italic state. | | align | "left" \| "center" \| "right" | "left" | Text alignment. | | wrap | boolean | true | Multi-line wrap vs single line. | | features | string[] | [] | Initially active OpenType feature tags. | | editable | boolean | true | Whether the sample is user-editable. | | placeholder | string | "Type to test…" | Empty-state placeholder (CSS, not real text). | | controls | ControlsConfig | {} | Which controls to render (see below). | | showValues | boolean | false | Show each control's value inline (e.g. Size: 96px). | | variable | Record<tag, AxisConfig> | — | Variable-font axes (see below). | | palette | string | "normal" | Initial colour-font palette (font-palette). | | synthesis | boolean | true | Allow faux bold/italic. false for honest proofing. | | ariaLabel | string | "Sample text" | Accessible name for the editable region. | | onChange | (state) => void | — | Called on every state change. |

When fontFamily is set, FontProof asks the browser (Font Loading API) to load the matching weight/style as you change them, so toggling italic or weight uses the real glyphs instead of a heavier-looking fallback.

Controls

controls selects which interactive controls appear. A true value uses the default range; an object overrides it:

controls: {
  size: { min: 12, max: 240, step: 1 }, // or `true`
  tracking: true,                       // em slider
  weight: true,                         // 100–900, or the variable axis
  italic: true,                         // aria-pressed toggle button
  align: true,                          // native <select>
  wrap: true,                           // single-line toggle
  features: true,                       // full OpenType list (or string[] subset)
  axes: true,                           // a slider per variable axis (or string[] subset)
  palette: ["normal", "light", "dark"], // colour-font palette <select> (or `true`)
}

Default ranges: size 8–300px, tracking -0.1–0.5em, weight 100–900 step 100.

Variable & colour fonts

Variable axes. Configure any axis by its 4-character tag in variable, then enable sliders with controls.axes. wght is special — it drives the weight control; all other axes (opsz, slnt, wdth, ital, or custom GRAD/SOFT/ WONK…) get their own slider and compose into one font-variation-settings.

new FontProof(el, {
  fontFamily: "Fraunces",
  variable: {
    wght: { min: 100, max: 900 },
    opsz: { min: 9, max: 144, default: 40, label: "Optical" },
    slnt: { min: -10, max: 0 },
  },
  controls: { weight: true, axes: true }, // weight = wght; opsz + slnt = axis sliders
});

When an opsz axis is configured, font-optical-sizing: none is set so your manual value isn't overridden by the browser's automatic optical sizing.

Colour fonts (COLR/CPAL — e.g. Nabla, Bungee Spice). They render in colour automatically; expose palette switching with controls.palette (sets font-palette). Use the keywords normal/light/dark, or custom palettes you define with @font-palette-values:

@font-palette-values --brand {
  font-family: Nabla;
  base-palette: 2;
}
controls: { palette: ["normal", "light", "dark", "--brand"] }

Honest proofing. Set synthesis: false to apply font-synthesis: none, so a missing bold/italic renders as the real font rather than a faux (synthesised) style — useful when proofing which weights/styles a family actually ships.

Static, bitmap (sbix/CBDT), SVG, emoji and icon fonts all work too — they need no special controls beyond size/features.

OpenType features

Unlike v1 (one feature at a time), features compose: selecting Small Caps and Oldstyle Figures yields font-feature-settings: "smcp" 1, "onum" 1.

import { FEATURES, featureSettings } from "fontproof";

featureSettings(["smcp", "onum"]); // => '"smcp" 1, "onum" 1'

Supported tags include ligatures (liga, dlig, hlig, clig), case (smcp, c2sc, case, cpsp), figures (lnum, onum, pnum, tnum, zero, ordn), fractions (frac, afrc), alternates (swsh, calt, salt, hist, nalt), position (sups, subs), and stylistic sets ss01ss20. Restrict the offered set with controls: { features: ["smcp", "onum", "ss01"] }.

Accessibility

  • Native <input type="range">, <button aria-pressed>, <select>, and checkbox feature toggles — full keyboard support out of the box.
  • Editable region is a labelled role="textbox" with aria-multiline; the placeholder is CSS-only, so screen readers never read stale text.
  • The features panel manages focus, closes on Escape / outside click, and exposes aria-expanded / aria-haspopup.
  • State changes are announced via a polite live region.
  • Toggle states use weight + colour (not colour alone); animations respect prefers-reduced-motion.

Styling & themes

The controls render as a slim, borderless segmented bar under the sample. It stays hidden until the tester is engaged — clicking the sample (or tabbing into any control) reveals it via :focus-within, and it collapses again when focus leaves. Each segment shows only its title by default; the control titles mix-blend-mode: difference against the bar so they stay legible over the slider fills. Set showValues to also show the value (Size: 96px). Import the stylesheet to get it:

import "fontproof/styles.css";

The look is monochrome by default and driven by CSS variables on the host:

| Variable | Default | Purpose | | --- | --- | --- | | --fp-accent | #000 | Focus rings, slider/checkbox accent | | --fp-bg / --fp-fg | #fff / #000 | Component background / text | | --fp-bar-bg | #fff | Bar background | | --fp-bar-track | #e5e5e5 | Unfilled slider track | | --fp-bar-fill | #000 | Filled slider track / pressed toggle | | --fp-bar-h | 26px | Bar (segment) height | | --fp-bar-radius | 6px | Bar corner radius | | --fp-speed | 0.18s | Reveal transition |

Override any of them, e.g. .fp { --fp-accent: #e11d48; }.

A faithful TDF green-on-black preset ships built in — add fp--tdf to the host:

new FontProof(el, { /* … */ });
el.classList.add("fp--tdf");
// React: <FontProofComponent className="fp--tdf" … />

Migrating from v1

| v1 (jQuery attributes) | v2 | | --- | --- | | class="typeTester" | data-fontproof (or new FontProof(el, …)) | | font="Inter" | data-font="Inter" / fontFamily: "Inter" | | size="90" / size="" (fit) | data-size="90" / data-size="fit" | | weightoptions="true" | data-controls="weight" / controls: { weight: true } | | optoptions="dlig,hlig" | data-features / controls: { features: [...] } | | magic words "yup", "nope" | plain booleans / "true" / "false" | | jQuery + jQuery UI + BigText | no dependencies |

The v1 source remains available at the v1.0.0 git tag.

Development

npm install
npm run build      # bundle ESM + CJS + types (tsup)
npm test           # vitest + jsdom
npm run typecheck  # tsc --noEmit
npm run dev        # watch build

License

ISC © Quinn Keaveney. Originally built for The Designers Foundry.