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

dockman

v0.4.0

Published

Build, tag, and push images with Docker or Podman from Bun and Node.

Readme

dockman

Build, tag, and push container images from Bun or Node with Docker or Podman, and deploy with kubectl. Install with bun add dockman. Requires Node 22+ or Bun 1.3+ and an engine CLI on PATH.

import { DockmanConnection } from 'dockman'

const connection = await DockmanConnection.create({
    preference: ['docker', 'podman'],
    startIfNeeded: true,
    interactive: true,
})

const image = await connection.build({
    context: '.',
    file: 'Dockerfile',
    buildArgs: { NODE_ENV: 'production' },
})
await connection.tag(image, 'ghcr.io/my-org/my-app:latest')
await connection.push('ghcr.io/my-org/my-app:latest')

Connecting

DockmanConnection.create(options?) checks engines in preference order, defaulting to Docker then Podman. Use ['podman'] or ['docker'] to restrict discovery. An already-running engine is used before attempting to start any engine. The readonly connection.engine identifies the selected engine; operations never fail over to a different image store. The CLI's existing environment and context/connection settings apply.

startIfNeeded defaults to true. Automatic startup is Windows-only: Dockman starts Docker Desktop or Podman's existing default machine and polls for readiness. startupTimeoutMs defaults to 120,000 per engine; individual probes have a five-second limit. Set startIfNeeded: false to require an already-running engine. On macOS/Linux, start engines yourself. Dockman does not install engines, initialize machines, elevate privileges, change connection defaults, or stop engines after use.

Docker launches use hidden windows as a best effort. Docker controls its dashboard; if it still opens, disable Open Docker Dashboard when Docker Desktop starts in Docker's settings. Dockman does not change saved preferences.

Images

  • build(options?) streams progress and returns a sha256: image ID. Options: context (default .), file, tags, buildArgs, labels, target, platform (one platform), and noCache. An automatically cleaned temporary iidfile avoids parsing progress output. Build arguments are not a safe channel for secrets.
  • tag(image, target) assigns one local name. Repeat it for additional tags.
  • push(reference) streams progress and uploads an explicitly tagged reference. Any registry can use existing engine credentials; automatic login supports GHCR only.

Kubernetes deployments

KubernetesConnection uses kubectl on PATH and existing kubeconfig credentials independently of Docker or Podman. Its constructor accepts context and namespace; omitted values use kubectl's current settings. It does not change kubeconfig or contact the cluster until a method runs.

import { KubernetesConnection, kustomizeBuild, kustomizeSetImage } from 'dockman'

const cluster = new KubernetesConnection({ context: 'production', namespace: 'my-app' })
await kustomizeSetImage('./k8s', 'ghcr.io/example/my-app:v2')
const yaml = await kustomizeBuild('./k8s')
const diff = await cluster.diff(yaml)
console.log(diff)

await cluster.apply(yaml, {
    dryRun: 'server', // Use 'none' to persist changes after your application's confirmation.
    serverSide: true,
    fieldManager: 'kustomize',
    applySet: 'my-app-deploy',
})

// After applying with dryRun: 'none':
// await cluster.rolloutRestart('deploy/deployment')
// await cluster.rolloutStatus('deploy/deployment', { timeout: '10m' })
  • diff(manifests, options?) returns the complete diff text and accepts kubectl exit codes 0 (unchanged) and 1 (differences). Other failures reject. Options include serverSide and fieldManager so previews can match apply semantics. kubectl requires a diff executable on PATH or KUBECTL_EXTERNAL_DIFF configured.
  • apply(manifests, options?) streams output. dryRun accepts 'none' (default), 'client', or 'server'. serverSide and fieldManager control field ownership. Setting applySet enables --prune --applyset=..., removing previously managed resources absent from the manifests. It sets KUBECTL_APPLYSET=true only for that subprocess.
  • rolloutRestart(resource) restarts a resource specified as type/name.
  • rolloutStatus(resource, { timeout? }) streams progress until the latest rollout finishes, rejecting on failure or timeout. Durations use kubectl syntax, such as '10m'; the default waits indefinitely. A newer rollout is followed if one starts while watching.

Manifests accept strings, Uint8Array (including Node buffers), or ArrayBuffer and are piped to stdin. Diff formatting and confirmation prompts remain in your script. See the kubectl reference for command behavior and prerequisites.

Kustomize utilities

These standalone utilities require kustomize on PATH and work without a cluster or container engine connection. Both require an explicit local directory containing the kustomization. Relative paths resolve from the current working directory; neither utility changes it.

  • kustomizeBuild(directory) returns the complete UTF-8 YAML string, ready for diff or apply.
  • kustomizeSetImage(directory, image) persists an image change to the local kustomization file. It accepts native image expressions such as ghcr.io/example/my-app:v2, my-app=ghcr.io/example/my-app:v2, and digest references.

Both reject on command failures with CLI diagnostics. They use the standalone executable without falling back to kubectl's bundled Kustomize.

GHCR login

On recognizable GHCR authentication failures, interactive: true (the default) allows GitHub CLI browser authentication in a terminal. Install gh beforehand. Dockman reuses the active account, requests write:packages when needed, logs the selected engine into ghcr.io using secret stdin, and retries the push once. GitHub CLI and the engine manage credential persistence through their usual stores. Generic permission denials, missing images, and network errors do not trigger login.

With interactive: false or no terminal, authentication failures include manual instructions. For example:

gh auth login --hostname github.com --web --scopes write:packages
# For an existing account that needs the package scope:
gh auth refresh --hostname github.com --scopes write:packages
gh auth token --hostname github.com | docker login ghcr.io --username YOUR_GITHUB_USERNAME --password-stdin

Replace docker with podman when appropriate. Verify package write permissions and organization SSO authorization. Environment-provided GH_TOKEN/GITHUB_TOKEN values take precedence in GitHub CLI; replace or unset insufficient tokens rather than attempting browser refresh. Configure registry credentials ahead of time in CI.

See GitHub CLI login and GHCR authentication.