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

@hrm-shell-app/coco

v0.1.0

Published

Claude Code devcontainer launcher and template

Readme

                ___
               /   \
              /=*=*=\
         ____/=======\____
        /~~~~~~~~~~~~~~~~\
        '-o-o-o-o-o-o-o-o-'

coco

Claude Code devcontainer launcher and template.

TL;DR

A shareable devcontainer for running Claude Code in a sandboxed Linux container with an egress firewall, plus a small CLI to drive it:

npm i -g @hrm-shell-app/coco
cd ~/some-project
coco init             # drop .devcontainer/ into the project
coco --up && coco      # build, start, attach
coco allow api.x.com  # punch a hole in the firewall, no restart
coco shadow my-app    # isolate my-app/node_modules from the host
coco kill             # tear it down

Why you'd want it: bind-mounts ~/.claude and ~/.ssh so Claude Code and git work out of the box, locks outbound traffic to a known allowlist, and gives every colleague the same container without sharing dotfiles. Adding new firewall domains and isolating per-project node_modules no longer requires a rebuild-loop.

Install

npm i -g @hrm-shell-app/coco

This also installs @devcontainers/cli as a dependency. Docker must be running.

Use

cd ~/some-project
coco init                       # writes .devcontainer/ into the current directory
coco --up                       # build/start the container
coco                            # attach (auto-starts if not running)
coco --up --rebuild             # rebuild from scratch
coco allow some-api.example.com # allow a new egress domain without restarting
coco kill                       # stop & remove this workspace's container
coco kill --all                 # stop & remove every devcontainer on the host

The container is identified by the workspace folder it was started with. By default that is the current directory; override with -w <path> or by setting COCO_WORKSPACE.

Where to run coco init

The directory you run coco init in becomes the workspace: it gets bind-mounted to /workspace/ inside the container, and that's the upper bound on what Claude (and everything else in the container) can see and edit. Two common patterns:

  • One devcontainer for the whole machinecoco init in ~/Projects/ (or wherever you keep all your repos). Claude can read and edit every subproject, which is great for cross-project work, refactors that span multiple repos, or having a single long-lived container. The trade-off is blast radius: Claude has reach into every project under that root.
  • One devcontainer per projectcoco init inside each project directory. Claude is scoped to just that project, which is safer and matches the "standard" devcontainer pattern, but you juggle one container per project and lose easy cross-repo access.

Pick based on how broad you want Claude's reach to be. You can also mix: keep a shared ~/Projects/.devcontainer/ for general work and add a more locked-down .devcontainer/ inside specific projects when you need it.

Node version

The container's Node version is controlled by the NODE_VERSION build arg (default 24). Override it per-host by exporting COCO_NODE_VERSION before coco --up --rebuild:

export COCO_NODE_VERSION=20
coco --up --rebuild

Node 24 ships with npm 11, which tracks platform-specific optional deps in the lockfile and avoids the esbuild/@swc/* mismatch you hit when one side ran npm install on macOS and the other on Linux.

Shadowing node_modules

For projects where you don't want the host and container sharing node_modules at all (cleanest fix for the cross-platform native binary problem), shadow the directory with a Docker named volume:

coco shadow my-project       # add a volume mount for my-project/node_modules
coco shadow my-project --remove
coco shadow                  # list active shadows
coco --up --rebuild          # required to apply

coco shadow edits the mounts array in .devcontainer/devcontainer.json between the // coco-shadows-start / // coco-shadows-end markers. Volume names are scoped to the workspace path so different colleagues' workspaces don't collide. The host's node_modules/ for that project becomes invisible to the container (and vice versa) — IDE features like "go to definition" into deps will need a host-side npm install too.

Adding domains to the firewall

coco allow <domain> [<domain>...] resolves each domain and adds its IPs to the live allowed-domains ipset inside the running container — no restart, no terminal loss. The domain is also appended to .devcontainer/allowed-domains.local (gitignored) so the next container start re-applies it automatically.

You can also edit .devcontainer/allowed-domains.local by hand (one domain per line, # for comments) — init-firewall.sh reads it on every start.

What's in the template

template/.devcontainer/ ships:

  • Dockerfile — Node 24 (configurable via NODE_VERSION build arg) + zsh + Claude Code, plus iptables/ipset for the egress firewall.
  • devcontainer.json — bind-mounts ~/.claude and ~/.ssh, persists shell history in a named volume, runs the firewall script on start.
  • init-firewall.sh — locks outbound traffic to GitHub, the npm registry, the Anthropic API, the VS Code marketplace, and the Tempo API. Edit the domain list in this file if you need other endpoints reachable from the container.

Publishing

The package is published as @hrm-shell-app/coco. Source lives at simployer/coco. To cut a release:

npm version patch          # or minor / major
npm publish                # uses publishConfig.access = "public"
git push --follow-tags