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

codaforge

v0.1.3

Published

Turn any Coda doc into clean Markdown or a searchable static site — faithfully, with no tool-specific bias.

Readme

coda-forge

Turn any Coda doc into clean Markdown or a searchable static site — faithfully.

Coda has no good export for canvas-heavy docs. Its API export and "copy as Markdown" both flatten tables, multi-column layouts, callouts, page icons, and embeds. But the published web renders everything correctly — as bespoke kr-* DOM, not semantic HTML, so naïve scrapers lose the same formatting the API does.

coda-forge reconstructs high-fidelity Markdown from that rendered DOM: nested lists, block & pull quotes, callouts, split-header tables, multi-column layouts, dividers, page icons, bold/italic/code, internal-link rewriting, and embed resolution (Coda proxies YouTube/Vimeo/SlideShare through iframely — these are resolved to native embeds). Then it can build a self-contained, searchable static site from the result.

No API token needed for public docs. Nothing about any specific doc is baked in.

Install

npm i -g codaforge      # CLI (installs `coda-forge` and `codaforge` commands)
# or use it ad-hoc:
npx codaforge --help

Scraping needs a Chromium. coda-forge uses playwright-core and will use your system Chrome/Edge automatically, or point it at a binary:

export CODA_FORGE_CHROME=/path/to/chrome     # optional

Quick start

# 1) A public Coda doc → a folder of clean Markdown (+ assets + embeds)
npx codaforge md https://yourdoc.coda.io/ -o ./out

# 2) A public Coda doc → a searchable static site
npx codaforge site https://yourdoc.coda.io/ -o ./site --title "My Docs"
npx serve ./site

# 3) A single saved Coda HTML file → Markdown (offline, no browser)
npx codaforge render page.html -o page.md

The site output is fully self-contained (HTML + one CSS + one JS + a JSON search index): a hierarchical sidebar mirroring the doc's page tree, client-side search, light/dark themes, image lightbox, and rendered video/slide embeds.

Config file

Drop a coda-forge.config.mjs in your project (auto-detected), or pass --config:

export default {
  source: { type: 'scrape', url: 'https://yourdoc.coda.io/', concurrency: 5 },
  output: './site',
  site: {
    title: 'My Docs',
    accent: '#2947d6',
    intro: 'Everything you need to know.',
    lenses: [
      // Config-driven "lenses": extra grouped index pages. The engine knows nothing
      // about your content model — you decide what to group and how.
      { id: 'guides', title: 'Guides', match: (p) => /guide/i.test(p.title) },
      { id: 'api',    title: 'API',    match: (p) => p.markdown.includes('## Endpoint') },
    ],
  },
};

See examples/startup-secrets.config.mjs for a real doc rebuilt with multiple lenses.

Private docs (Coda API)

For docs you own, use the API source (no browser needed):

export default {
  source: { type: 'api', docId: 'AbCdEf', token: process.env.CODA_API_TOKEN },
  output: './site',
};

| | Scrape (rendered DOM) | Coda API | |---|---|---| | Auth | none — any public doc | token + doc access | | Private docs | ✗ | ✓ | | Fidelity (canvas) | high | Coda's export (lossier) | | Needs a browser | yes | no |

Programmatic API

import { codaHtmlToMarkdown, forge, forgeSite, generateSite } from 'codaforge';

// Pure: HTML → Markdown + metadata (no I/O, no browser)
const { title, icon, markdown, embeds, links } = codaHtmlToMarkdown(html, {
  title: 'My Page',
  links: { rewrite: (slug) => `/docs/${slug}` },
});

// Whole doc → forged pages
const pages = await forge({ source: { url: 'https://doc.coda.io/' } });

// Whole doc → static site
await forgeSite({ source: { url: 'https://doc.coda.io/' }, output: './site' });

Sub-path exports: codaforge/transform, codaforge/source, codaforge/site.

What it handles

  • Split-header tables — Coda renders the header row as a separate, duplicated sticky bar; coda-forge reunites it with the body and drops the duplicate.
  • Emphasis through zero-width chars — Coda sprinkles zero-width characters that break Markdown bold/italic delimiters; these are stripped first.
  • iframely embeds — proxied YouTube/Vimeo become native embeds; SlideShare decks keep the (cross-origin-embeddable) iframely URL.
  • Collapsed nav — the whole page tree is expanded before discovery; hierarchy is derived from visual indentation, so it works regardless of Coda's CSS classes.
  • Page icons, callouts, block/pull quotes, multi-column layouts, dividers.

Limitations

  • Interactive Coda widgets (fillable tables, buttons, live formulas) can't be reproduced — they appear as static content or links.
  • The API source uses Coda's async export, which is lossier than the rendered DOM for heavily-formatted canvases.
  • Images are referenced at their original (Coda CDN) URLs by default.

License

MIT © soup up (soupup.ai)