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

dayzero

v0.2.0

Published

Auth once per machine. One command provisions every service a new project needs and writes .env.local.

Downloads

270

Readme

dayzero (d0)

Auth once per machine. Then one command provisions every service a new project needs (repos, databases, DNS, API keys), writes .env.local, and unblocks your agent.

d0 init            # scaffold stack.yaml
d0 login github    # interactive, once per machine — tokens go to the OS keychain
d0 up              # non-interactive: provision everything, write .env.local

Principles

  1. Human auths, agent provisions. Anything needing a browser or MFA is a login concern. up runs with zero prompts — a missing login is a structured, machine-readable error naming the exact fix.
  2. Zero-knowledge, zero backend. No dayzero servers. Credentials live in your OS keychain and travel only from your machine to the provider's API.
  3. Secrets never enter the agent. Agents learn env var names and status, never values.
  4. Idempotent. Running d0 up twice is safe — state-file reconciliation, not blind creation.
  5. Least privilege. Project-scoped, minimally-permissioned keys wherever the provider supports it.

dayzero is not Terraform. It provisions the start of a project, not ongoing infra state. If a resource needs ongoing declarative management, that's your IaC tool's job.

Commands

d0 init [project]         # scaffold stack.yaml
d0 login <provider|all>   # interactive auth → OS keychain
d0 logout <provider>      # revoke where possible + remove from keychain
d0 status [--json]        # auth state + provisioned resources
d0 up [--only a,b] [--dry-run] [--json]
d0 down [--only a,b] [--yes]
d0 env [--check] [--json] # env var names + presence (never values)
d0 doctor                 # keychain, token validity, API reachability
d0 exec [--only a,b] -- <cmd>   # run a command with provider credentials injected
d0 mcp                    # MCP server (stdio) for agent use

Running provider tooling

Credentials live in the keychain, so a provider's own CLI cannot see them. d0 exec bridges that gap — it injects each provider's expected variable (CLOUDFLARE_API_TOKEN, SUPABASE_ACCESS_TOKEN, NEON_API_KEY, GH_TOKEN, …) plus your env file into a child process, and nowhere else:

d0 exec -- wrangler deploy
d0 exec -- supabase db push
d0 exec --print-env          # names only, never values

This keeps the secret out of your shell history, out of an agent's context, and out of a second credential store. Without it, tooling has to be authenticated separately — which is how you end up with two credentials for the same provider and only one of them managed.

MCP server

d0 mcp exposes the same core to agents over the Model Context Protocol (stdio). Register it with Claude Code:

claude mcp add d0 -- d0 mcp

Six tools: check_auth, provision_plan, provision_stack, get_env_status, open_login, teardown (refuses without confirm: true). No tool ever returns a secret value — a redaction layer scrubs every payload before transport, on top of handlers that only deal in env var names. Errors are structured: { provider, code, humanFix, agentRetryable } — when auth is missing, the agent relays the humanFix line (e.g. d0 login railway) and the human does the one interactive step.

stack.yaml

version: 1
project: acme-dashboard
providers:
  github:
    repo: acme-dashboard
    private: true
env:
  file: .env.local

Status

Early, macOS only for now (keychain via the security CLI, zero native deps).

| Provider | Auth | Provisions | Env vars | |---|---|---|---| | github | device flow / PAT | repo | GITHUB_REPO_URL | | supabase | PAT | project + keys | SUPABASE_URL, SUPABASE_ANON_KEY, SUPABASE_SERVICE_ROLE_KEY, SUPABASE_DB_PASSWORD, DATABASE_URL | | cloudflare | PAT | Pages, R2, KV, DNS, wrangler.jsonc | CLOUDFLARE_ACCOUNT_ID, CLOUDFLARE_PAGES_URL, CLOUDFLARE_R2_BUCKET_*, CLOUDFLARE_KV_*_ID | | neon | PAT | Postgres project | NEON_PROJECT_ID, DATABASE_URL | | railway | PAT | project, services, project token | RAILWAY_PROJECT_ID, RAILWAY_TOKEN | | resend | PAT | API key, sending domain | RESEND_API_KEY | | webflow | PAT | CMS collections, webhooks (site must already exist) | WEBFLOW_SITE_ID, WEBFLOW_API_TOKEN, WEBFLOW_COLLECTION_*_ID |

Webflow is a partial provider by necessity. Webflow has no site-creation endpoint — sites are built in the Designer — so d0 resolves an existing site (auto if the token sees exactly one, else set site:) and provisions what the API does support: CMS collections and webhooks. d0 down removes collections and webhooks d0 created and never touches the site.

Webflow multi-site access (OAuth)

A Webflow site token reaches exactly one site, and d0 stores one credential per provider — so with site tokens you can only wire up one Webflow site per machine. Workspace tokens do not solve this: their only scope is workspace_activity:read (audit logs), they can't reach site endpoints at all, and they're Enterprise-only.

The real multi-site path is an OAuth App, where Webflow asks which sites to authorize. Register one once:

  1. Create an App at webflow.com → Workspace settings → Apps & integrations → Develop an App.
  2. Set its redirect URI to exactly http://localhost:4471/callback.
  3. Request scopes sites:read, sites:write, cms:read, cms:write.
  4. Run d0 login webflow. The first time, it asks whether you have an app and prompts for the Client ID and Secret (found under Apps & Integrations → App Development), then stores them in your keychain. Every later login skips straight to the browser.
$ d0 login webflow
Webflow site tokens reach a single site. An OAuth app lets you authorize several sites at once.
◇ Do you have a Webflow App registered? › Yes
◇ Webflow App Client ID › ...
◇ Webflow App Client Secret › ...
✓ Webflow authenticated as Acme Site, Other Site

d0 opens Webflow, you pick the sites, and the callback lands on a loopback listener bound to 127.0.0.1 — never exposed to the network. Choose which site a project uses with site: in stack.yaml.

Answer "no" and login falls back to the site-token paste, warning that it reaches only one site. D0_WEBFLOW_CLIENT_ID / D0_WEBFLOW_CLIENT_SECRET still take precedence when set, which is the path to use in CI. Override the port with D0_OAUTH_PORT (it must match the registered redirect URI), and D0_OAUTH_HOST=127.0.0.1 if you'd rather register the literal loopback address per RFC 8252.

webflow:
  site: acme                 # optional: id, shortName, or displayName
  collections:
    - Blog Posts             # slug + singular derived; or { name, singular, slug }
  webhooks:
    - { trigger: form_submission, url: https://api.example.com/webflow }

Wrangler config

Set wrangler: true on the Cloudflare block and d0 writes a wrangler.jsonc wiring up the bindings it just provisioned — real KV namespace ids, R2 bucket names, and your account id — so wrangler deploy works without hand-wiring anything:

cloudflare:
  r2: [uploads]
  kv: [cache]
  wrangler: { buildOutputDir: ./dist }   # or just `wrangler: true`

An existing wrangler.jsonc is never overwritten: d0 writes its version to wrangler.jsonc.d0 alongside and warns, so you (or an agent) can merge. Verified by running wrangler types against a generated config — it resolved KVNamespace and R2Bucket bindings correctly.

GitHub, Supabase, Neon, Cloudflare, Resend, and Webflow verified live against real accounts (Webflow via OAuth across 13 sites: collection created, re-run adopted without duplicating, teardown removed the collection and left the site and its other collections untouched). Railway is tested against API fixtures only. Generated secrets that providers only return once (DB passwords, project tokens, minted keys) are kept in the keychain so re-running up always reproduces a complete .env.local.

GitHub auth uses OAuth device flow when D0_GITHUB_CLIENT_ID is set; otherwise it opens the token-creation page with the right scopes preselected and validates the pasted PAT before storing.

Development

npm install
npm run build      # tsup → dist/cli.js
npm test           # vitest (includes a live macOS keychain round-trip)
node dist/cli.js --help