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

doczero

v0.2.1

Published

Terminal-native documentation platform — browse docs in the CLI; same commands for humans and agents.

Readme

doc0

Terminal-native documentation: humans browse in a TUI; agents run the same CLI with --json / raw output, or talk to the MCP server.

doc0 is the primary command; d0 is installed as a short alias. Everything below works with either.

Install

npm install -g doczero

The package name on npm is doczero (the shorter doc0 was blocked by npm's similarity filter). It installs the same two binaries — doc0 and d0 — so every command in these docs works as written.

Interactive browse (doc0 @scope/pkg, doc0 browse …) uses the Ink + React TUI only — Node 22+ and npm install are enough; there is no Rust or native binary.

Use doc0 browse --external <url> for live docs URLs when you want off-site links from llms.txt included in discovery.

Experimental secondary track: doc0 browse-opentui runs a parallel OpenTUI shell (requires Bun).

From source:

npm install
npm run build
node dist/index.js --help

Add ~/.d0/bin to your PATH to use named bundle CLIs (e.g. stripe-docs) after doc0 add.

Quick start

# Point doc0 at any markdown folder — name + version inferred from package.json when present.
doc0 add ./my-docs
doc0 @local/my-docs

# Or install a packaged bundle dir that ships with d0.json.
doc0 add --local ./examples/example-lib
doc0 @example/lib
# TUI: j/k scroll, Enter open, / search, h back, l forward, q quit

# See which of your project's deps have built-in docs coverage.
doc0 scan

# Verify every registry entry (bundles installed, URLs serve llms.txt / llms-full.txt / sitemap).
doc0 doctor

doc0 @example/lib search webhooks --json
doc0 @example/lib read api/webhooks --raw
doc0 ls --json

Commands

For most users, three commands are enough:

  • doc0 <id> — open docs in the TUI (doc0 stripe)
  • doc0 mcp install — wire doc0 into your agent client
  • doc0 add ./my-docs — install local markdown as a bundle

Everything else is available under doc0 contrib for maintainer/power-user workflows.

| Command | Description | |--------|-------------| | doc0 add <path> | Instant bundle. Point at any folder of markdown — doc0 scans .md / .mdx, infers name from package.json (or @local/<dirname>), bundles, and installs in one step. Pass --name @scope/x to override. | | doc0 add --local <dir> | Install an existing bundle directory that already has d0.json (strict). | | doc0 add <@scope/name> | Registry name (network registry not live yet). | | doc0 remove <name> | Remove an installed bundle | | doc0 ls | List installed bundles | | doc0 <bundle> | Open Ink interactive browser (TTY) | | doc0 <bundle> ls | List pages (slugs) | | doc0 <bundle> read <slug> | Read one page | | doc0 <bundle> search <query> | Full-text search | | doc0 browse-opentui | Experimental secondary OpenTUI launcher (Bun required) | | doc0 scan [dir] | Scan ./package.json deps and report which have doc0 registry coverage | | doc0 ask <id> <question...> | Ask a question against a docs source; returns cited answer (--json for agents) | | doc0 update [--check] | Self-update the CLI from npm. --check reports without installing. | | doc0 mcp | MCP server on stdio. --installed-only hides built-in URL sources; only user-added entries + installed bundles are exposed. | | doc0 mcp install | Add doc0 as an MCP server to a supported client. Interactive picker by default; use --cursor / --claude-code / --windsurf to skip the prompt. Merges into the target config, backing up any existing file. | | doc0 contrib … | Maintainer workflows: bundle build/import/init, ingest, doctor, registry sync |

Flags: --json and --raw where documented; without a TTY, read defaults to raw markdown and search/ls default to JSON when outputFormat is auto in ~/.d0rc.

Bundle format

See examples/example-lib/d0.jsonstructure maps stable slugs to markdown paths. Bundle name must be scoped (@org/name).

MCP

Run the server on stdio:

doc0 mcp

Cursor: merge doc0 into Cursor's MCP config (global ~/.cursor/mcp.json by default):

doc0 mcp install --cursor            # install into ~/.cursor/mcp.json
doc0 mcp install --cursor --project  # use ./.cursor/mcp.json in this repo
doc0 mcp install --cursor --yes      # replace existing mcpServers.d0
doc0 mcp install --cursor --dry-run  # print JSON only

Claude Code: merge doc0 into Claude Code's MCP config:

doc0 mcp install --claude-code            # install into ~/.claude.json (user scope)
doc0 mcp install --claude-code --project  # install into ./.mcp.json (project scope, team-shareable)

Windsurf: merge doc0 into Windsurf's MCP config:

doc0 mcp install --windsurf          # install into ~/.codeium/windsurf/mcp_config.json

Antigravity: merge doc0 into Antigravity's MCP config:

doc0 mcp install --antigravity       # install into ~/.gemini/antigravity/mcp_config.json

Zed: merge doc0 into Zed's settings (uses context_servers key):

doc0 mcp install --zed               # install into ~/.config/zed/settings.json
doc0 mcp install --zed --project     # install into ./.zed/settings.json

OpenCode: merge doc0 into OpenCode's config (uses mcp key):

doc0 mcp install --opencode          # install into ~/.config/opencode/opencode.json
doc0 mcp install --opencode --project  # install into ./opencode.json
doc0 mcp install                     # interactive picker
doc0 mcp install --list              # show supported clients

Restart the client after install. The entry is registered under mcpServers.d0 (or context_servers.d0 for Zed, mcp.d0 for OpenCode).

Tools

Four tools, designed to minimize round-trips in an agent loop:

| Tool | Purpose | |------|---------| | find_docs(query) | Registry search. Returns matches + for the top match: root tree inline and whether /llms-full.txt is available. Usually one call is enough to start navigating. | | read_docs(id, path?, full?) | Read docs by registry id. No path → root tree; dir path → subtree; page URL/slug → page markdown. full=true → whole /llms-full.txt markdown; full="heading substring" → a single matching chunk. Pages are cached on first read. | | grep_docs(id, query) | Search within a source. Uses the local cache of pages you've read; for uncached URL docs falls back to bounded live search (cap via D0_MCP_SEARCH_MAX_FETCH). | | list_docs() | List all registry entries. | | ask_docs(id, question) | One-call Q&A with citations (uses your configured provider key). |

Tool-flow guidance for agents

Fast path when you just need an answer:

  1. ask_docs("stripe", "how do I verify webhook signatures?") — single call, answer + citations.

Detailed path when you need full source context:

  1. find_docs("stripe webhooks") — one call returns the id, the root tree, and an llms_full_available flag.
  2. If llms_full_available is true: read_docs("stripe", null, true) returns the entire docs site in one HTTP hit, or read_docs("stripe", null, "webhook") returns just the matching section. This is the fast path for most modern doc sites.
  3. Otherwise navigate: read_docs("stripe", "/api/webhooks"). Every page you read is cached under ~/.d0/docs-store/<id>/ so subsequent grep_docs calls are local.
  4. Use grep_docs once pages are cached, or for sites without /llms-full.txt when you need text search.

Registry

Registry entries resolve from, in order of precedence:

  1. User overrides: ~/.d0/docs-registry.json
  2. Installed bundles (anything added via doc0 add)
  3. Community registry — a single JSON file on GitHub, fetched once a day and cached at ~/.d0/community-registry.json
  4. Shipped seedregistry.json bundled with the npm package (offline / first-run fallback)

Community registry

Every doc0 install points at the community registry by default:

https://raw.githubusercontent.com/doc0team/d0-registry/main/registry.json

That repo is a single JSON file. PRs are the curation UI — no servers, no accounts. See the template at examples/d0-registry-template/ for the README, contributing rules, and validation workflow that go in that repo.

The shipped seed (registry.json at the root of this package) is a point-in-time snapshot of the community file, refreshed before each publish via npm run sync-registry. It exists so doc0 works on a fresh install with no network and so first-run latency is zero. Community entries with the same id override seed entries, so stale seed data is fixed by a one-line PR to d0-registry.

Commands:

doc0 registry status        # show configured URL + cache state
doc0 registry sync          # force-refresh the cache right now

Control it from ~/.d0rc:

# Point at your own fork / private mirror
registryUrl: https://raw.githubusercontent.com/myorg/d0-registry/main/registry.json

# Or disable entirely (shipped seed only, no network call)
registryUrl: false

Or from the environment (wins over ~/.d0rc):

D0_REGISTRY_URL=off doc0 ls                 # disable for this run
D0_REGISTRY_URL=https://… doc0 stripe       # override for this run

Fetch failures fall back to the last-known-good cache, then to the shipped seed, so doc0 keeps working offline.

Format of the JSON file (array or { "entries": [...] }):

{
  "entries": [
    {
      "id": "stripe",
      "aliases": ["stripe api", "stripe docs"],
      "sourceType": "url",
      "source": "https://docs.stripe.com",
      "description": "Stripe API documentation"
    }
  ]
}

Bootstrapping a new d0-registry repo: copy registry.json from this package root, plus the files under examples/d0-registry-template/ (README, CONTRIBUTING, GitHub Actions workflow).

Local override

To add or override a single source without touching the community file, edit ~/.d0/docs-registry.json:

{
  "entries": [
    { "id": "my-docs", "aliases": ["mydocs"], "sourceType": "url", "source": "https://example.com/docs" }
  ]
}

There is still no doc0-hosted registry service. Everything resolves from the shipped seed + a GitHub-hosted JSON file + your local files.

URL docs completeness (env)

Large doc sites can return tens of thousands of URLs from sitemaps and llms.txt. doc0 caps work in layers so runs stay predictable; raise caps when you want maximum coverage (more time, disk, and HTTP load).

Multilingual sitemaps. Many sites (e.g. Starlight on Astro) list every locale in the sitemap (/en/…, /es/…, …). When doc0 detects a large, multi-locale URL set from the sitemap, it keeps a single language catalog so the TUI and discovery stay usable. It prefers, in order: D0_DOCS_LOCALE if set and present in the sitemap; else the locale implied by your browse URL’s first path segment; else en if present; else the locale with the most URLs. URLs whose first path segment does not look like a locale tag (two letters or xx-yy) are left unchanged. Set D0_DOCS_LOCALE=off or D0_DOCS_LOCALE=* to disable filtering and keep every locale from the sitemap.

| Variable | What it controls | Default | |----------|------------------|---------| | D0_DOCS_LOCALE | Force one locale for sitemap-derived pages (en, pt-br, …), or off / * to keep all languages | unset (auto when heuristics match) | | D0_MAX_DISCOVERED_URLS | Max URLs kept after merging llms.txt, sitemaps, and nav discovery | 50000 | | D0_MAX_SITEMAP_NESTED | Max nested sitemap index pages to follow | 200 | | D0_SEARCH_MAX_FETCH | Live searchDocUrls (CLI/TUI): max pages to fetch and scan for a query (0 = all discovered up to D0_MAX_DISCOVERED_URLS) | 10000 | | D0_MCP_SEARCH_MAX_FETCH | MCP search_nodes live URL search: max pages to consider (uses URL-ranking + early exit; avoids multi-hour scans on huge sites) | 80 | | D0_SEARCH_FETCH_CONCURRENCY | Parallelism for that live search fetch pass | 8 | | D0_INGEST_MAX_PAGES | ingestUrlToDocStore / CLI ingest: max pages after dedupe (0 = all discovered up to D0_MAX_DISCOVERED_URLS) | 50000 | | D0_INGEST_FETCH_CONCURRENCY | Parallelism when writing ingested markdown pages | 8 | | D0_LLMS_FULL_CHUNK_MAX_CHARS | Max characters per llms-full.txt chunk (paragraph-bounded; continuation chunks share the heading as (part N/M)) | 8000 | | D0_MCP_INSTALLED_ONLY | Set to 1 to hide community + seed URL entries in MCP (equivalent to doc0 mcp --installed-only) | unset | | D0_REGISTRY_URL | Override the community registry URL. Disable tokens: off / false / disabled / "". | default URL | | D0_COMMUNITY_REGISTRY_TTL_MS | How long to trust ~/.d0/community-registry.json before re-fetching | 86400000 (24h) | | D0_DEBUG | Set to 1 to surface community-registry fetch failures in MCP mode (stderr is otherwise silent there) | unset |

CLI: doc0 ingest url accepts --max-pages (same semantics: 0 means no extra cap beyond discovery).

License

MIT