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

daedalus-ui

v0.1.0

Published

Daedalus UI — decorative letter library

Readme

daedalus-ui

Daedalus UI — decorative SVG letter library. Glyphs ship as TypeScript vector data (per-letter modules); there are no shipped .svg asset files.

Install

bun add daedalus-ui

Dev setup

bun install

Usage

TypeScript

import { families, listFamilies, listGlyphs, getGlyph, findGlyphs, renderSvg } from "daedalus-ui";

console.log(listFamilies()); // ['slinky', 'elegant', 'fast-furious', 'sports-sliced']
console.log(families); // [{ id, name, glyphCount }, ...] (counts from the registries)

// Exact char match; no variant -> first in reading order.
const a = getGlyph("slinky", "a"); // { family, char, bbox, body, defs }
const sTagline = getGlyph("fast-furious", "s", "line03-1"); // explicit variant

// All variants of a char, in reading order.
const sAll = findGlyphs("fast-furious", "s"); // 4 entries: line02, line03-1, line03-2, line06

// Distinct chars of a family, in reading order.
console.log(listGlyphs("elegant").length); // 62

// Standalone SVG artwork for a word.
const svg = renderSvg("elegant", "Hello 123", { padding: 4 });

JavaScript (ESM)

import { getGlyph, findGlyphs, listGlyphs, renderSvg } from "daedalus-ui";

console.log(getGlyph("slinky", "a").bbox);
console.log(findGlyphs("fast-furious", "a").map((g) => g.variant)); // ['line04-1', 'line04-2', 'line05']
console.log(listGlyphs("sports-sliced").join("")); // 'abc...z'
console.log(renderSvg("slinky", "slinky").slice(0, 38)); // '<?xml version="1.0" ...'

Errors

Matching is exact and case-sensitive. Unknown families throw Unknown family; unknown chars, variants, or text characters throw Unknown glyph:

getGlyph("nope", "a"); // throws Unknown family: nope
getGlyph("slinky", "A"); // throws Unknown glyph (slinky ships lowercase only)
getGlyph("fast-furious", "s", "nope"); // throws Unknown glyph (no such variant)
renderSvg("elegant", "hi!"); // throws Unknown glyph ('!' is not covered; nothing is silently skipped)

renderSvg layout

renderSvg(family, text, opts?: { tracking?: number; padding?: number; className?: string }) lays text out left-to-right with a cursor that advances by each glyph's bbox width plus tracking:

  • Default tracking = 8% of the per-render median glyph width (computed from the bbox widths of the glyphs in that render; family-wide median fallback when the text holds no letters).
  • The space character advances without artwork at 40% of that median.
  • Output is a standalone SVG string: XML declaration first, then <svg viewBox="0 0 W H" ...> sized to the content plus padding, one <defs> block uniting the used glyph defs exactly once, and each glyph body nested in <g transform="translate(x y)"> at its x-offset.
  • Limitation: no kerning pairs — advances are purely bbox-width + tracking.
  • Companion CSS: styles/fonts.css exposes per-family --dl-tracking custom props (same 8%-of-median rule, em-scaled) for wrapping elements.

Example output shape (abridged):

<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1458.63 251.97" width="1458.63" height="251.97">
<defs>
  ...family defs used by these glyphs, exactly once...
</defs>
<g transform="translate(-218.75 -223.47)">
  ...glyph body paths...
</g>
...
</svg>

CSS

Link the tracking-utility stylesheet:

<link rel="stylesheet" href="node_modules/daedalus-ui/styles/fonts.css" />
<div class="dl-elegant">wrapped renderSvg artwork</div>

See styles/fonts.css for all four family classes. These are spacing utilities only — they carry no artwork and reference no asset files.

Coverage

| family | id | chars covered | glyph modules | variants | notes | | -------------- | --------------- | ---------------------------------- | ------------- | --------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | | Slinky | slinky | a–z (lowercase, 26) | 26 | none | bare single-case alphabet | | Fast & Furious | fast-furious | 0–9 + a–z (lowercase, 36 distinct) | 57 | variant = line id (line01, line02, line03-1, line03-2, line04-1, line04-2, line05, line06, …) | digits on line01; tagline words lines 02–04 (multi-size dupes, e.g. s × 4); full specimen a–z lines 05–06 | | Sports Sliced | sports-sliced | a–z (lowercase, 26) | 26 | line02 (a–o), line03 (p–z) | one size per letter | | Elegant | elegant | 0–9 + a–z + A–Z (62) | 62 | line01 (digits), line04 (lowercase), line05 (UPPERCASE) | only family with both cases; match is exact |

Extras (slinky coils, ff/sliced/elegant backgrounds, headers, titles, diagonals) exist as code modules but are EXCLUDED from the letter APIs: the family registries list only single alphanumeric chars, so decoration art can never come back from getGlyph/findGlyphs/listGlyphs/renderSvg.

No shipped assets

No .svg files ship with this package — and since T15 none remain in the repo either. The artwork lives only as inline vector data in src/glyphs/ (per-letter TypeScript modules); package.json files covers dist/ + styles/ only, and the packed tarball contains zero .svg files. Consumers get vector data via the API above, never files.

Source history (removed in T15, user decision 2026-09-24): the Vecteezy originals at the repo root and their assets/*.svg extraction copies were deleted once the glyph modules were frozen — re-extraction is no longer possible from this repo. (scripts/extract-glyphs.ts was kept as a historical record until T16, then removed too — recoverable via git history. The repo is private and src/ is the source of truth.)

Build

bun run build

This runs the prebuild clean (rm -rf dist, so stale pre-rename modules can never linger) then tsc (TypeScript 7), emitting dist/ (compiled from src/ with strict mode). prepack rebuilds dist/ automatically before packing or publishing.

bun pm pack --dry-run

Changelog

  • 0.1.0 (pre-publish, T18): migrated to ESM ("type": "module", tsc module: NodeNext, .js extensions on all 521 relative imports) + exports map + "sideEffects": false for tree-shaking. Drops CJS require() support (breaking-for-0.x before first publish). (Version stays 0.1.0, never published.)
  • 0.1.0 (pre-publish, T15): deleted ALL .svg files from the repo (5 root Vecteezy originals + 5 assets/ extraction copies + 20 smoke/*.svg QA sheets) and then removed smoke/ entirely (validator + labels.json — repo is private, src/ is the source of truth). Artwork lives only as inline vector data in src/glyphs/. (T16: scripts/extract-glyphs.ts removed as well — recoverable via git history. Version stays 0.1.0, never published.)
  • 0.1.0 (pre-publish, T12): public glyph API replaces asset paths. resolveAsset (and listIds) removed — use getGlyph / findGlyphs / listGlyphs / listFamilies / renderSvg instead. assets/ no longer ships (extraction source only); styles/fonts.css no longer references asset files (tracking utilities now). Positional glyph ids are gone — variant (line id) disambiguates dupes. (Version stays 0.1.0, never published.)
  • 0.1.0 (pre-publish): removed the sports-minimal family from the library (user decision T11c: hard to read, not worth it). The package ships 4 families. The root vecteezy_sports-minimal-tech-…svg source file stays in the repo as source material. (Version stays 0.1.0, never published.)
  • 0.1.0 (pre-publish): dropped the kawaii family from the library. This is noted as a breaking-for-0.x change before the first publish (version stays 0.1.0, never published).

License

MIT — see LICENSE.