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

ensure-running

v1.0.0

Published

Chainable CLI and API to ensure local services are ready before running commands

Readme

ensure-running

Chainable CLI to ensure local services are ready before running commands

er docker postgres -- vite dev - ensure services, then run your script.

npm version License: MIT Node.js TypeScript Runtime Dependencies Vitest

Get Started • Features • CLI • Services • Development


What Is ensure-running?

ensure-running is a CLI and library for chaining readiness checks before a command runs. Instead of one-off shell scripts per dependency, you compose services on the command line or in package.json scripts.

  package.json script
         |
         v
   er docker postgres -- vite dev
         |
    +----+----+
    |         |
    v         v
 docker     postgres
 (built-in) (.er/services)
    |         |
    +----+----+
         v
    vite dev (spawned with inherited stdio)

The first built-in service is Docker. More built-ins (Postgres, Redis, etc.) can be added under src/services/. Projects can also define custom services in .er/services/.


Features

  • Chainable CLI: er docker, er docker -- vite dev, er docker postgres -- npm test.
  • Docker service: install detection via docker --version, daemon checks via docker info, cross-platform auto-start.
  • Custom services: drop files in .er/services/ with export default defineEnsureService({ ... }).
  • Library API: ensureRunning, ensureDocker, ensureDockerRunning, and typed Docker errors from one package.
  • Service registry: extensible core with parse/run contracts.
  • package.json friendly: one command prefix instead of nested shell scripts.
  • Fully tested: mocked child_process in unit tests - no real Docker required in CI.

Get Started

Install

npm install ensure-running

CLI

er docker
er docker --check
er docker -- vite dev
ensure-running docker --timeout 60000 -- npm test

| Invocation | Behavior | |------------|----------| | er docker | Ensure Docker is installed, started, and ready | | er docker --check | Exit 0 only when the daemon responds; never auto-start | | er docker -- vite dev | Ensure Docker, then run vite dev | | er docker postgres -- npm test | Chain services, then run command (postgres = custom or future built-in) |

-- is required before the command. Without it, er docker vite dev is an error.

Custom services (.er/services)

Create project-local services that the CLI discovers automatically:

.er/
  services/
    postgres.ts
import { defineEnsureService } from "ensure-running";

export default defineEnsureService({
    id: "postgres",
    parseArgs(argv) {
        return { options: {}, remaining: argv };
    },
    async run() {
        // wait for postgres, return 0 or 1
        return 0;
    },
    printHelp() {
        console.log("postgres - ensure local Postgres is ready");
    }
});

Then chain it like a built-in service:

er docker postgres -- npm run migrate

package.json

{
    "scripts": {
        "dev": "er docker -- vite dev",
        "test:integration": "er docker -- vitest run --config vitest.integration.ts",
        "db:up": "er docker postgres -- npm run migrate"
    }
}

Use -- to separate services from the command. It is required when running a trailing command.

API

import {
    ensureRunning,
    runEnsureRunning,
    ensureDocker,
    ensure
} from "ensure-running";

// Chain services (same model as the CLI)
await ensureRunning(["docker"]);

await ensureRunning({
    services: [
        { service: "docker", options: { timeout: 60_000 } }
    ]
});

// Ensure, then spawn a command (like `er docker -- vite dev`)
const exitCode = await runEnsureRunning({
    services: ["docker"],
    command: ["vite", "dev"]
});

// Docker shorthand with typed errors
await ensureDocker();
await ensure.docker({ check: true });

// Low-level docker helpers (re-exported from ensure-running)
import { ensureDockerRunning, detectDocker } from "ensure-running";
await ensureDockerRunning({ autoStart: true });

| API | Description | |-----|-------------| | ensureRunning(services) | Ensure one or more services; throws EnsureRunningError | | ensureRunning({ services, command? }) | Same, with optional structured request | | runEnsureRunning({ services, command? }) | Ensure services, then spawn command; returns exit code | | ensureDocker(options?) | Docker-only helper; throws DockerError subclasses | | ensure.docker() / ensure.running() | Namespaced aliases |


CLI

Global options

| Flag | Description | |------|-------------| | -h, --help | Show top-level help | | -v, --version | Print CLI version | | er docker --help | Docker service help |

Docker service flags

| Flag | Description | |------|-------------| | --check | Exit 0 when daemon is reachable; never auto-start | | --timeout <ms> | Max wait for readiness (default: 120000) | | --interval <ms> | Poll interval (default: 1000) | | --no-auto-start | Fail when daemon is down | | -q, --quiet | Suppress progress output |

Bin names

| Command | Package | |---------|---------| | er | ensure-running | | ensure-running | ensure-running |


Services

Built-in services ship inside ensure-running. Custom services live in .er/services/.

| Service | Source | Description | |---------|--------|-------------| | docker | built-in (src/services/docker) | Docker detection, auto-start, polling, typed errors | | * | .er/services/* | Project-local export default services |

Public exports

| Export | Description | |--------|-------------| | ensureRunning(services) | Chain services programmatically | | runEnsureRunning(request) | Ensure services, then run a command | | ensureDocker(options?) | Docker shorthand with typed errors | | ensure | { docker, running } namespace | | runCli(argv) | Programmatic CLI entry (returns exit code) | | createServiceRegistry() | Built-in + .er/services registry | | createBuiltInServiceRegistry() | Built-in services only | | defineEnsureService(service) | Define a custom or built-in service with type checking | | EnsureService | Service contract type | | EnsureRunningError | Service failure with serviceId and exitCode | | ensureDockerRunning(options?) | Full Docker install + daemon + readiness flow | | isDockerRunning() | Returns true when daemon is reachable; never throws | | detectDocker() | { installed, running, version?, executable? } | | dockerService | CLI service object for custom registries | | DockerError subclasses | Typed errors with stable code values |


Architecture

src/
  cli/       -> core (parseInvocation) + services (registry)
  api/       -> core + services/docker
  services/
    docker/  -> ensure / detect / wait / platforms / commands / utils
    LoadCustomServices.ts  -> .er/services/*

See ARCHITECTURE.md for module graphs, platform start order, and how to add services.


FAQ

How is this different from ensure-docker-running?

This repo ships Docker as a built-in service. The CLI is ensure-running / er with service names as the first tokens.

Does er docker -- vite run vite on PATH?

Yes. Tokens after -- are spawned as a command with inherited stdio (shell: true on Windows).

WSL2 / Colima / Rancher Desktop

Works when docker info succeeds in the same environment as the Node process. WSL bridging is not automatic.

Linux permissions

If docker info fails with permission denied, add your user to the docker group. This tool does not change system permissions.


Development

From Pacotes/ensure-running/:

npm ci
npm test
npm run lint
npm run typecheck
npm run build
npm run test:coverage

Run the CLI from source:

yarn dev docker
yarn dev docker --check
yarn dev docker -- vite --version

Link the published bins:

npm run build
npm link
er docker --version

| Script | Purpose | |--------|---------| | yarn dev docker ... | Run CLI via tsx without building | | npm run build | Build library + bin | | npm test | Vitest unit tests | | npm run ci | Lint, typecheck, coverage, and build (same gate as release) | | yarn deploy | Local publish (prefer CI tag releases) |

Publish (GitHub Actions + npm Trusted Publishing)

Releases are published from CI when you push a v* tag. No NPM_TOKEN secret is required - npm authenticates the workflow via OIDC.

One-time setup on npmjs.com:

  1. Package settings -> Trusted publishing -> GitHub Actions
  2. Owner callmeteus, repo ensure-running, workflow publish.yml
  3. Allow action npm publish

Release:

# bump version in package.json first
git tag v1.0.1
git push origin v1.0.1

CI validates lint/tests/build, checks that the tag matches package.json, then runs npm publish with provenance.

See docs/PUBLISHING.md for full setup, npm requirements, and troubleshooting.

Local publish (fallback)

npm run deploy

Requires npm login against registry.npmjs.org. If you use Yarn globally, this repo pins npm via .npmrc and publishConfig.registry so yarn deploy does not target registry.yarnpkg.com. Prefer tag-based CI releases.

Requires Node.js >= 20.


Documentation

| Document | Contents | |----------|----------| | docs/PUBLISHING.md | npm Trusted Publishing, tags, CI release flow | | ARCHITECTURE.md | Package layout, service contract, Docker internals, custom services | | LICENSE | MIT |


License

MIT