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

snoutdata

v0.4.0

Published

Hosted Postgres from a terminal or an agent. Create a database, get a DATABASE_URL, run migrations, and serve the same operations to an AI agent over MCP.

Readme

snoutdata

Hosted Postgres from a terminal, or from an agent. One bundled file with no dependencies, so npx snoutdata is a download rather than an install. Needs Node 20 or newer.

npx snoutdata init --env

An empty folder becomes a folder with a working database: a project is created, the command waits until it is actually serving, writes .snoutdata/project.json, and puts DATABASE_URL in .env. It is idempotent, so running it twice gives you the same project, not two.

Driven end to end holding nothing but an access token (no browser, no session, no human) in 21 seconds, with a DATABASE_URL that connected on the first try.


For an agent

This CLI is built to be driven by a program. The contract, which every command holds:

| | | | --- | --- | | --json | Accepted everywhere. Exactly one JSON value on stdout and nothing else, so a pipe into jq needs no filtering. Progress, warnings and prompts go to stderr. | | Failures are structured | In --json mode a failure is {"ok":false,"code":"...","error":"..."} on stdout. Including a bad flag, a bad command, and a bad credential. | | No prompts | Nothing asks a question when stdin is not a terminal, or under --json, or in CI. A command that would have to ask says which flag to pass and exits 2 immediately, rather than blocking on a question nobody will answer. | | Unknown flags are errors | Never ignored. A typo that quietly does something else is worse than a stop. | | Typed exit codes | The code says what kind of problem it was, so a caller can decide whether to retry, re-authenticate, or give up. |

Exit codes

| Code | Meaning | What a caller should do | | --- | --- | --- | | 0 | Fine | Continue. | | 1 | The operation failed | Read the error. | | 2 | The command was wrong | Fix the call. Do not retry. | | 3 | The credential is no good | Never signed in, expired, or revoked. The message says which. | | 4 | Not ready yet | Retry. | | 5 | Forbidden | Do not retry. | | 6 | Not found | Do not retry. | | 7 | Conflict | | | 8 | Over a quota | The plan's limit. Do not retry. | | 9 | Network | Retry. | | 10 | Timed out | Retry, or raise --timeout. | | 127 | A tool this command needs is not installed | The message names it. The shell’s own convention, so a CI log reads right. |

Credentials, without a browser

export SNOUTDATA_ACCESS_TOKEN=sdt_...   # made once by a person: snoutdata tokens create

SNOUTDATA_ACCESS_TOKEN outranks everything and never expires, which is what CI and an agent should use: a script's behaviour should not depend on who happens to be logged in on the machine it runs on. Failing that, ~/.snoutdata/auth.json (written by snoutdata login, mode 0600), whose session lasts an hour.

The token is exchanged for a short-lived session by the control plane, so row-level security is still the only thing deciding what it can see.

As an MCP server

snoutdata mcp

Serves the operations below as tools over stdio, so an agent configures one server instead of being handed a connection string. Anything destructive is off unless you pass --allow-delete, and it is present-but-refusing rather than absent, so an agent can tell you what to turn on instead of inventing something else.

If the SnoutData desktop app is running on the same machine, its own database tools are borrowed onto the same endpoint under an app_ prefix, so one configured server covers both the cloud and the databases already set up locally. SNOUTDATA_NO_DESKTOP=1 opts out.


Commands

Setup

snoutdata init [--name X] [--env]     # a database for this folder, linked and ready
snoutdata link --ref R                # point this folder at an existing project

Auth

snoutdata login                       # through a browser
snoutdata login --sso                 # your company's identity provider; asks for a work email
snoutdata login --sso --domain acme.com   # or name the domain and skip the question
snoutdata login --device              # print a code to type into a browser anywhere
snoutdata login --no-browser          # print the URL instead of opening one
snoutdata logout
snoutdata whoami
snoutdata tokens create --name ci [--expires DAYS]
snoutdata tokens list
snoutdata tokens revoke <id|sdt_prefix>

Projects

snoutdata projects list
snoutdata projects create --name X [--region R] [--no-wait]
snoutdata projects pause|resume|delete [--ref R]
snoutdata usage [--ref R] [--days 30] [--history]
snoutdata teams

Database

snoutdata db url [--ref R]                        # a connection string
snoutdata db psql [--ref R] [-- ...]              # opens psql, no password typed
snoutdata db reset-password [--ref R]
snoutdata db export [--ref R] [--out FILE]        # take a dump and download it
snoutdata db push [--dir migrations] [--dry-run]  # run the .sql files, once each
snoutdata db restore --file DUMP [--force]

Types

snoutdata gen types typescript [--ref R] [--schema public] [--out FILE]
snoutdata gen types typescript --db-url postgres://...   # any Postgres, ours or not
snoutdata gen types typescript --local                   # the database `snoutdata start` runs

Your schema as a TypeScript Database type, on stdout. Read out of pg_catalog, so an enum column says mood and a generated column is optional on insert.

Local

snoutdata start [--port 54322] [--dir migrations] [--no-migrations]
snoutdata stop                        # the data stays
snoutdata status                      # running, how big, on what port

A Postgres on your own machine, the same build as a hosted project, with migrations/*.sql and seed.sql applied on the way up, using the same migration ledger db push uses, so a folder means the same thing here and in the cloud. It publishes on 54322 by default, which is where supabase start puts its Postgres, so a .env written for one works against the other; pass --port if you run both at once.

It needs Podman (not Docker, and deliberately with no fallback: a database that works under Docker and not under Podman is one that works here and not in the cloud). The database image is fetched from ghcr.io/snoutdata/snoutpod-postgres the first time you run it, which takes a few minutes once and nothing after that. Nothing else in this CLI needs anything installed at all.

Agents

snoutdata mcp [--allow-delete]

Every command takes --json, --quiet and --help, and anything that waits takes --timeout SECONDS. snoutdata --help --json returns the whole command surface as JSON.


Where things come from

A project, in order: --ref, then SNOUTDATA_PROJECT, then .snoutdata/project.json in this folder or a parent.

A token, in order: SNOUTDATA_ACCESS_TOKEN, then ~/.snoutdata/auth.json.

Sign-in, when there is no credential and a person is present, in order: the SnoutData desktop app if it is running here and willing, then a browser, then a pairing code for a terminal that has no browser at all. With no person present (not a terminal, --json, CI, or SNOUTDATA_NO_INTERACTIVE) nothing is asked and it exits 3 at once.


Documentation

SnoutData Cloud is hosted Postgres that costs nothing when idle: a database pauses when nobody is using it and wakes on the next connection, while the client waits.


© SnoutData. See https://snoutdata.com/terms.