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

@snackbyte/spec-render

v0.1.1

Published

Render Spec Kit Markdown artifacts to interactive HTML — sticky auto-TOC, collapsible sections, anchored headings, syntax highlighting, task timelines, spec dashboards, plan views, cross-artifact nav, and lazy Mermaid.

Readme

@snackbyte/spec-render

Render Spec Kit Markdown artifacts to interactive, self-contained HTML views — a render library and a spec-render CLI that ship together off the same code.

Markdown stays the source of truth (clean for the Spec Kit skill chain and for git/GitHub); this produces a sibling .html view per .md file, wrapped in a styled shell:

  • Sticky auto-TOC with scroll-spy, collapsible sections, anchored headings
  • Syntax highlighting (highlight.js) and priority/status badges
  • Purpose-built views for the three primary artifacts:
    • tasks.md → a roadmap timeline (phase chips with progress rings, drill-in panels)
    • spec.md → a skimmable dashboard (priority-badged user-story cards, filterable FR/SC requirements)
    • plan.md → a navigable plan (Technical Context grid, Constitution-Check principle cards)
    • everything else (research.md, data-model.md, quickstart.md, …) → a clean readable view
  • A cross-artifact nav bar linking the sibling artifacts of one feature
  • Lazy Mermaid — the client-side renderer (loaded from jsDelivr) is injected only when a ```mermaid block is present; there is no Mermaid npm dependency

Requirements

  • Node.js >= 24 (ESM-only package)

Install

npm install @snackbyte/spec-render

Or run the CLI without installing:

npx @snackbyte/spec-render

CLI usage

The CLI resolves paths against the current working directory — run it from your repo root. With no argument it renders every .md under ./specs.

spec-render                 # render every ./specs/**/*.md
spec-render <path>          # render one .md file, or a directory (recursively)
spec-render --watch [path]  # render, then re-render on save (Ctrl-C to stop)
spec-render --clean [path]  # remove the generated .html alongside each .md

Each <name>.md produces a sibling <name>.html. Those .html files are derived artifacts — git-ignore them (e.g. specs/**/*.html).

Wire it into a project's package.json scripts:

{
  "scripts": {
    "spec:html": "spec-render",
    "spec:html:watch": "spec-render --watch",
  },
}

Library usage

All render functions are pure (string in, HTML string out); only renderFile touches the filesystem.

import { renderArtifact, renderMarkdown, renderFile } from '@snackbyte/spec-render';
import { readFile } from 'node:fs/promises';

// Dispatch to the right view based on the artifact filename:
const src = await readFile('specs/007-widget/tasks.md', 'utf8');
const html = renderArtifact(src, { name: 'tasks.md', title: 'Widget Tasks' });

// Or force the generic readable view for any Markdown:
const page = renderMarkdown('# Notes\n\nAnything.', { title: 'Notes' });

// Or read a .md and write its sibling .html in one call:
await renderFile('specs/007-widget/plan.md', { specsRoot: 'specs' });

Exports

| Export | Kind | Description | | ---------------------------------------------------------------- | -------------------------- | ----------------------------------------------------------------------------------------------------------------- | | renderArtifact(src, opts) | (string) => string | Render Markdown, dispatching to the tasks/spec/plan view by opts.name (falls back to the generic view). | | renderMarkdown(src, opts) | (string) => string | Render Markdown to the generic readable view (TOC, badges, highlighting, lazy Mermaid). | | renderFile(mdPath, opts) | async (string) => string | Read a .md, render it, write the sibling .html, return its path. Discovers sibling artifacts for the nav bar. | | renderTasksTimeline / renderSpecDashboard / renderPlanView | (string) => string | The three purpose-built views directly. | | looksLikeTasks / looksLikeSpec / looksLikePlan | (string) => boolean | Content predicates the dispatch uses. | | navBar(opts) / NAV_STYLES / NAV_KEYS | markup / CSS / keys | The shared cross-artifact nav bar building blocks. |

opts for the render functions: { title?: string, nav?: object }. renderArtifact also takes { name?: string } (the artifact filename used to pick a view). renderFile takes { specsRoot?: string } (the root the feature label is made relative to).

Releases

Released from CI by npm trusted publishing; every version on the registry carries a provenance attestation naming the commit and workflow that built it. RELEASING.md is the runbook; npm run smoke:pack and npm run smoke:registry are the checks that run before a publish.

Development notes

This package ships its .mjs source as-is, with no build — the recorded opt-out from the template's TypeScript default. The reason is in DECISIONS.md §4: the render logic is a verbatim graft of working JavaScript, and full strict would mean rewriting it. npm run check:all is the gate (format, lint, a relaxed checkJs typecheck, the publish-contract check, tests); CLAUDE.md carries the rules for agents.

License

MIT © Jeff Fichtner


Part of the snackbyte ecosystem; the first package spun out of the snackbyte-npm-base template line.