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

@supapool/cli

v0.4.1

Published

Acquire and release disposable Supabase instances

Readme

@supapool/cli

Disposable Supabase instances for coding agents, tests, and local development.

npx @supapool/cli run -- npm run dev

Supapool leases a clean, isolated Supabase instance from a warm pool, applies your repository's supabase/migrations, injects standard Supabase and Postgres environment variables into the wrapped command, renews the lease while the command runs, and releases the instance when it exits. Your repository's environment files are never modified.

Requires Node.js 18 or newer (needs built-in fetch). The hosted beta is free.

Commands

The CLI has two commands.

run

npx @supapool/cli run -- <command> [args...]

Everything after -- runs with a leased instance in its environment. Examples:

npx @supapool/cli run -- pnpm test        # CI or a one-shot test run
npx @supapool/cli run -- npm run dev      # a dev server for a working session

The lease lives exactly as long as the wrapped command. When the command exits, the instance is released and its slot is wiped for the next caller. If the process dies without releasing, the lease stops renewing and expires on its own.

For local development, embed the wrapper in the dev script so plain npm run dev works for everyone, including coding agents:

{
  "scripts": {
    "dev": "supapool run -- next dev"
  },
  "devDependencies": {
    "@supapool/cli": "latest"
  }
}

Embed it at one level only. run always acquires a fresh instance, even when invoked inside an existing lease, so a wrapped script wrapped again would lease two instances.

On first use, run opens GitHub sign-in and saves an API key automatically, so login is rarely needed as a separate step.

login

npx @supapool/cli login

Opens GitHub sign-in in the browser and saves the session and a default API key to ~/.config/supapool/config.json with mode 0600. The key secret is not printed.

What gets injected

The wrapped command receives standard Supabase credentials:

  • SUPABASE_URL
  • SUPABASE_ANON_KEY and SUPABASE_PUBLISHABLE_KEY
  • SUPABASE_SERVICE_ROLE_KEY and SUPABASE_SECRET_KEY
  • DATABASE_URL
  • SUPAPOOL_INSTANCE_ID

The same values are mirrored to the aliases most stacks expect:

  • Framework public prefixes: NEXT_PUBLIC_, VITE_, PUBLIC_, EXPO_PUBLIC_, REACT_APP_, GATSBY_, and NUXT_PUBLIC_ variants of the URL and publishable key.
  • Database URL aliases: SUPABASE_DB_URL, DIRECT_URL, POSTGRES_URL, POSTGRES_PRISMA_URL, POSTGRES_URL_NON_POOLING, and DB_URL.
  • Standard connection variables: PGHOST, PGPORT, PGDATABASE, PGUSER, PGPASSWORD, and their POSTGRES_* equivalents.

Existing custom variables whose names end in recognized Supabase URL or key names are also redirected to the leased instance. Secret and service-role keys are never assigned to browser-public variables.

Migrations

Before starting your command, run applies every .sql file in supabase/migrations in filename order and records them in supabase_migrations.schema_migrations, matching the Supabase CLI convention. Repositories without a migrations directory skip this step.

The library API does the same: acquire({ root }) applies the repository's migrations before returning the instance, and releases the instance if a migration fails. Omit root to acquire without touching the database.

Migration statements run in file order without an implicit transaction. This supports PostgreSQL commands that require autocommit, including CREATE INDEX CONCURRENTLY. A session advisory lock serializes concurrent appliers, and a migration is recorded only after all of its statements succeed. Migration files may use their own BEGIN and COMMIT when they need transactional behavior. Failures name the file and line, for example Migration 20260722223000_prefab_toolbox.sql failed (line 3): ....

Seeding

After migrations, run executes the ordered seed files configured by [db.seed].sql_paths in supabase/config.toml. File paths, directory paths, and glob patterns are supported. Without configuration, the default remains supabase/seed.sql. Setting [db.seed].enabled to false disables seeding. Seed statements use the same session lock and autocommit behavior as migrations, and each seed file is recorded after every statement succeeds. A seed file may manage its own transaction when needed. Failures name the file and line.

Leases

Every instance is a lease with a TTL, 30 minutes by default. The CLI renews the lease every 5 minutes while the wrapped command is alive. There is no manual renew: a lease is kept alive by a running process and expires when renewals stop. Expired leases are garbage collected and their slots wiped, so nothing stored in an instance survives release.

Set SUPAPOOL_TTL_SECONDS to change the TTL for a run.

CI

CI jobs skip the browser login. Sign in once on a laptop, copy the API key from ~/.config/supapool/config.json into a CI secret, and expose it as SUPAPOOL_API_KEY:

- run: npx @supapool/cli run -- pnpm test
  env:
    SUPAPOOL_API_KEY: ${{ secrets.SUPAPOOL_API_KEY }}

GitHub Actions runs get an owner label derived from the run ID, so leases are traceable per workflow run.

Programmatic API

The package is also a library. withInstance acquires a lease, renews it while your callback runs, and always releases it when the callback returns or throws:

import { withInstance } from '@supapool/cli'

await withInstance(async (instance) => {
  const { SUPABASE_URL, SUPABASE_ANON_KEY, DATABASE_URL } = instance.env
  // use the instance; the lease stays renewed until this returns
})

instance.env contains the full injected variable set described above. Options such as ttlSeconds pass through to acquisition:

await withInstance(fn, { ttlSeconds: 600 })

The lifecycle primitives are exported for code that manages its own lease boundaries:

import { acquire, release, startRenewer } from '@supapool/cli'

const instance = await acquire()
const stop = startRenewer(instance)

try {
  console.log(instance.env.SUPABASE_URL)
} finally {
  stop()
  await release(instance)
}

renew(instance) is also exported for a single manual renewal, and runWithInstance(command, args, options) is the engine behind supapool run.

Environment variables

  • SUPAPOOL_API_KEY: API key for headless use. Overrides the saved config.
  • SUPAPOOL_API_URL: hosted API endpoint override for CI.
  • SUPAPOOL_TTL_SECONDS: lease TTL, default 1800.
  • SUPAPOOL_TELEMETRY_DISABLED=1: disables run telemetry.

Support

The hosted beta is free. Email [email protected] for an immediate automated response with a fix or a request for the information needed to solve it. See supapool.io for docs and community support.