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

@letterstory/design

v0.1.16

Published

Letterstory design tokens, the phantom theme registry, and the design principles — one source for every Letterstory repo.

Readme

@letterstory/design

The cross-repo layer of Letterstory's design system: the tokens (colour, radius, font, type scale), the phantom theme registry Lettersprite renders, and the design principles as a shipped file. Framework-neutral data with one thin adapter per framework, so every Letterstory repo reads the same values and none of them copies a palette.

Zero runtime dependencies, no build step to install. Published from this directory by .github/workflows/publish-design.yml (npm Trusted Publishing, on merge to main); design-version-guard.yml requires a version bump whenever a shipped file changes.

What ships

| File | What it is | | --------------------- | -------------------------------------------------------------------------------------------------- | | tokens.json | Source. The token values as one grouped object: color.{light,dark}, radius, font, size | | tokens.css | The tokens as CSS custom properties on :root, with the dark overrides under .dark | | tailwind-v4.css | A @theme inline block mapping the custom properties to Tailwind v4 theme keys | | tailwind-v3.cjs | A Tailwind v3 preset whose theme.extend references the custom properties | | styled.js + .d.ts | A plain object of resolved values (no stylesheet needed) for styled-components and similar | | themes.json | Source. The phantom theme registry: groups and themes (value, label, hint, group, tags) | | themes.d.ts | Literal-union types for the registry (PhantomBlogTheme, PhantomBlogThemeGroup, …) | | PRINCIPLES.md | The design principles, copied from the root AGENTS.md of the letterstory repo |

tokens.json and themes.json are the sources. Everything else is generated by scripts/build.mjs and committed; a test regenerates and diffs, so editing a generated file by hand fails CI. To change a value: edit the JSON, run node design/scripts/build.mjs, commit both.

In tokens.json, color.dark holds only the values that differ from light (exactly what the .dark block sets); styled.js resolves that into a full dark palette. Derived tokens keep their CSS expressions (brand-light is oklch(from var(--brand) …), radius.sm is calc(var(--radius) - 4px)), so rebranding is one value: color.light.brand.

Consuming it

Tailwind v4 (letterstory, lettersprite): import the tokens, then the mapping, after Tailwind itself.

@import "tailwindcss";
@import "@letterstory/design/tokens.css";
@import "@letterstory/design/tailwind-v4.css";

bg-brand, text-accent-peach, text-rising, rounded-lg, text-2xs now resolve to the tokens. --font-sans / --font-mono are set under Tailwind's own names, so font-sans and preflight's default pick up DM Sans with no mapping. Dark mode is the .dark class (@custom-variant dark (&:is(.dark *)) in your stylesheet).

Tailwind v3 (lettertrace, kernels): load tokens.css on the page and add the preset.

// tailwind.config.js
module.exports = {
	darkMode: "class",
	presets: [require("@letterstory/design/tailwind-v3")],
};

styled-components (the marketing repo): a resolved object, no stylesheet.

import { tokens } from "@letterstory/design";
// tokens.color.light["accent-peach"] === "#ee724a"; tokens.color.dark.background; tokens.font.sans

Plain CSS (admin, the company site): import tokens.css and use var(--brand), var(--accent-peach), var(--radius), var(--font-size-2xs) …

Theme registry (lettersprite, letterstory):

import registry from "@letterstory/design/themes"; // themes.json, typed by themes.d.ts
import type { PhantomBlogTheme } from "@letterstory/design/themes";

The registry says which looks a customer may choose; src/themes/ in lettersprite says what each one is. Neither half is complete alone, and an unregistered theme is unpickable while an unimplemented one silently renders the default. src/themes/registry.test.ts there asserts both directions against this package, so a theme added at either end cannot land alone.

Where the values come from

The letterstory app is a consumer, not a source: src/app/globals.css imports design/tokens.css and design/tailwind-v4.css by relative path and defines no token of its own, and src/types/deployments.ts re-exports themes.json as PHANTOM_BLOG_THEMES. Edit design/tokens.json or design/themes.json, never globals.css. The principles in PRINCIPLES.md are generated from the root AGENTS.md; edit that.

Versioning

Bump version in package.json whenever a shipped file changes (the guard enforces it); the merge to main publishes. Adding a token or a theme is a minor bump; changing a value is a patch; renaming or removing a token is a major.