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

@edspencer/paddock

v0.63.0

Published

Project-first launchpad for Claude Code: server-hosted, persistent, resumable sessions organized by project.

Readme

Paddock

Project-first launchpad for Claude Code — server-hosted, persistent, resumable sessions organized by project, in a web UI.

npx @edspencer/paddock

Then open http://127.0.0.1:4000.

Or point it at work you've already done — see Open your own project.

First run downloads ~250 MB. Paddock drives Claude Code, and the Claude Agent SDK ships a per-platform binary of that size. It cannot be skipped — installing with --omit=optional produces a Paddock whose chats all fail. Later runs reuse the npm cache and start immediately. For repeated use, npm i -g @edspencer/paddock is friendlier than bare npx.

Credentials

Paddock runs Claude Code on your behalf, so it needs Claude credentials:

claude setup-token                  # Claude Max/Pro
export ANTHROPIC_API_KEY=sk-ant-…   # or API billing

If you already use Claude Code on this machine, there is nothing to do. Paddock keeps a Claude home of its own under the data dir, but not a login of its own: it uses the one you already have — the macOS Keychain entry on a Mac, your ~/.claude/.credentials.json elsewhere (symlinked in, never copied). Reading a login writes nothing, and nothing else is shared with it.

To give Paddock its own instead, set claude: { credentials: own } in <data-dir>/paddock.config.yaml; a login is then a token in the environment as above, or a one-off CLAUDE_CONFIG_DIR=<data-dir>/claude-home claude login. Either way, Paddock says at startup if it can find no credentials at all.

What else Paddock does and does not take from your ~/.claude

Apart from that login: nothing, by default. Your CLAUDE.md, agents/, commands/ and plugins/ are not loaded, the hooks your settings.json binds to tool use do not run, your transcripts are not touched, and your ~/.claude.json MCP servers are not attached. Each is one key in <data-dir>/paddock.config.yaml:

claude:
  transcripts: host    # own | host, default own — whose session transcripts
  credentials: host    # own | host, default host — the one shared by default
  instructions: host   # own | host, default own — CLAUDE.md, agents, commands, plugins
  hooks: host          # own | host, default own — shell commands settings.json binds
  mcpServers: host     # own | host, default own — the servers in your ~/.claude.json

instructions: own is worth knowing about if you have curated a ~/.claude/CLAUDE.md: your Paddock agents will not see it until you set host. Each project's own CLAUDE.md always applies. hooks is off by default because inheriting someone's shell commands is not a thing to discover after the fact; the rest of your settings.json — permissions, model, statusline — applies either way.

To give this instance an MCP server your machine does not have — the case host cannot serve — declare it in a sibling mcpServers: block of the same file, using env:VAR_NAME anywhere a string goes so the token stays out of the git-tracked file (keep driveMode on its default session for a server holding a credential — batch passes the definition to claude as a command-line argument, where any local user can read it):

mcpServers:
  notion:
    command: npx
    args: ["-y", "@notionhq/notion-mcp-server"]
    env:
      NOTION_TOKEN: env:NOTION_TOKEN

Open your own project

cd ~/code/some-project        # somewhere you've used Claude Code
npx @edspencer/paddock --here

--here opens that directory as Paddock's workspace: Claude works in your files, and any Claude Code sessions you already have for the directory are offered for import. It's the fastest way to see what Paddock does with real history instead of an empty instance. Later runs in the same directory resume it — no flag needed.

The flag is the consent, so here is everything it does:

  • creates .paddock/ for the workspace's state and .chats/ for transcripts
  • appends those two entries to .gitignore

Nothing is written into your ~/.claude — no file, no symlink. Paddock uses a Claude home of its own under .paddock/ and relocates transcripts into .chats/. Sessions found in ~/.claude are offered for import: nothing is moved, copied or linked until you confirm, and your terminal claude keeps working exactly as before. To share one set of transcripts between Paddock and your terminal instead, set claude: { transcripts: host } in <data-dir>/paddock.config.yaml. (Your login is already shared, which is why there is nothing to log into — see Credentials above.)

To undo it: rm -rf .paddock .chats and drop the two .gitignore lines.

Without --here, Paddock never touches the directory you ran it from.

Options

  -p, --port <port>       HTTP/WS port (default 4000)
      --host <host>       Bind address (default 127.0.0.1)
  -d, --data-dir <path>   Projects + state (default ~/.paddock)
      --here              Open the CURRENT directory as the workspace
  -o, --open              Open the app in your browser once it is listening
      --verbose           Show the server's own logs (quiet by default)
  -v, --version           Print the version
  -h, --help              Show help

Your projects, chats and settings persist between runs in ~/.paddock — or in <dir>/.paddock when you use --here. Either way it's one directory: move it to move your instance, delete it to start over.

Security

Paddock binds loopback only with authentication disabled, which is the right default for a laptop. It refuses to start if you bind a routable interface while auth is off — to expose it on a network, configure PADDOCK_AUTH_MODE first. See AUTH.md.

Requirements

Node.js 22 or newer.

Other ways to run it

A multi-arch Docker image is published alongside this package, and is the better fit for a server deployment:

docker run -d -p 127.0.0.1:4000:4000 -v /srv/paddock-data:/data \
  -e CLAUDE_CODE_OAUTH_TOKEN=… \
  -e PADDOCK_DANGEROUSLY_ALLOW_OPEN=1 \
  ghcr.io/edspencer/paddock:latest

PADDOCK_DANGEROUSLY_ALLOW_OPEN=1 is required: the image binds 0.0.0.0 and the default auth mode is none, and Paddock refuses to bind a routable interface unauthenticated unless told to. Publishing on 127.0.0.1: is what makes that safe — Paddock runs code and spends Claude tokens, so put an auth mode or a reverse proxy in front of it before exposing the port to a network.

Links

MIT © Ed Spencer