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

ghosty-cli

v0.44.1

Published

Ghosty — deploy applications safely, from a short interview to a live URL.

Readme

ghosty-cli

The CLI for Ghosty — a platform that lets non-technical employees deploy applications in a safe, controlled environment: from a short interview to a live URL.

npm i -g ghosty-cli
ghosty login       # prints a link + short code — approve it in the console
mkdir my-app && cd my-app
ghosty templates   # starters your workspace offers (optional)
ghosty init        # short interview, scaffolds the app (or: ghosty init --template <id>)
ghosty provision   # repo + build pipeline + database + live URL
ghosty dev         # run it locally

Commands

| Command | What it does | | --- | --- | | ghosty login | Sign in with a link and a short code: it prints To sign in, open <link> and approve "<this computer>" (code XXXX-XXXX). Waiting…, you approve in the console at console.whiteghost.ai (where you're already signed in, and pick the workspace), and the command finishes on its own. No browser is needed on the machine running the CLI, so it works inside coding assistants and on remote machines. --company <slug> / --admin-url <url> / an app folder (--dir) only suggest a workspace on the approve page. --json prints {"event":"device_code","url","user_code","expires_in"} before waiting, then {ok, email, adminUrl, company, productName} — never a token. Errors: LOGIN_TIMEOUT, LOGIN_DENIED, NOT_A_MEMBER, WORKSPACE_NEEDS_UPDATE. --browser is the old browser sign-in on this computer (deprecated); --no-browser is accepted as the default. Set GHOSTY_CONSOLE_URL to override the console origin (local dev). | | ghosty clone <slug> | Put an app's code on this computer (./<slug>, or --dir; must be new or empty): git clone of its repository when git is installed, otherwise — or when this computer has no repository access yet — a download of the code. Then cd <dir> && ghosty dev. --json: {ok, dir, via: "git" \| "download"}; NO_ACCESS when it isn't an app you own or collaborate on. For an app whose code is kept on your workspace, it downloads the version the workspace deploys, records it as the folder's starting point (.ghosty/snapshot.json, git-ignored — what ghosty deploy checks against), and starts a local git history when git is installed (no remote); --json: {ok, dir, via: "snapshot", version}. | | ghosty whoami | Show the signed-in builder, GitHub username, and apps. | | ghosty templates | List the starters your workspace offers — complete apps (with sample data) to begin from: id, name, what each includes, who can open it by default, whether it uses a database. Runs from any folder. --json: {ok, available, items}; a workspace without starters answers {ok: true, available: false, items: []} (exit 0). | | ghosty init | Scaffold a new app (interview; all answers available as flags; --yes for defaults). In a terminal the interview first asks "Start from a template?" (only in a new or empty folder) and skips the brief question when you pick a starter. | | ghosty init --template <id> | Start from one of your workspace's starters (ghosty templates). It needs a new or empty folder (--dir <folder> creates one), so none of your files are overwritten: the starter is set up beside it and moved in whole, and a file that appears there meanwhile stops it (DIR_NOT_EMPTY). The starter decides the database, file storage and who can open the app; an invite-only starter stays invite-only where your workspace makes invite links for apps set up from the CLI (ghosty provision then prints the link); on an older workspace it starts public, and init says so. Settings a starter needs a private value for (e.g. HOST_KEY for its host link) get a fresh random value in app.config.json → env; ghosty provision applies them, and STARTER.md says how to change one (edit it, run ghosty provision). Node only (--backend python → TEMPLATE_BACKEND). --json adds template {id, name, version}, fileStorage, accessMode, derivedEnv (names) and hostUrl when there is a host link. Errors: UNKNOWN_TEMPLATE, DIR_NOT_EMPTY, TEMPLATE_UNAVAILABLE, DOWNLOAD_FAILED, WORKSPACE_NEEDS_UPDATE (a workspace from before starters). | | ghosty provision | Create everything the app needs on the platform and wait until it's ready. For an app whose code is kept on your workspace, the folder's code (binaries too) is uploaded first — unless someone deployed a newer version since this folder's code, in which case only the setup runs and ghosty deploy decides. A new app's first setup carries its binary files (a starter's images and fonts) when the workspace reads them, within the setup's 5 MB; anything left over is named, with how to send it (--json: skippedBinary, skippedBinaryNext). A provision that stops part-way (a failed step, or the MCP watch cap) still connects the folder to the app's repo once the platform has made it, and says so (--json event repo-connected). A database app that has no migration yet is set up but not live: provision says its first version goes live with the first ghosty deploy (--json: awaitingFirstMigration: true, next). An invite-only app's invite link — the link people need to open it — is printed at the end (--json: inviteUrl). Steps and failures are named in plain language ("Provisioning failed while creating the live service: …"); --json events accepted {plan} and state {summary, resources} carry kind + label per step (name only when it is the app's slug or a secret's name), rows shaped as in ghosty state --json. | | ghosty deploy | Ship the app. Repository apps: commit + push, then build. Apps whose code is kept on your workspace: pack the folder (the .gitignore applies; .env* files are refused; files up to 20 MB, binaries included), upload it, and build it — no git remote or credentials needed; a local git commit is kept when the folder is its own repo. If someone deployed a newer version since this folder's code, it stops with STALE_BASE (who and when); --force replaces their version. A repository app whose folder has no origin is connected to the app's repo first (--json event repo-connected {repoUrl, git}); NO_REMOTE only when the platform has no repo for the app. First migration: a Node app with a database whose schema has models but no migration yet gets its first one, init, created from the schema against your dev database (the same steps as ghosty migrate init) and shipped in the same deploy — once; after that, ghosty migrate <name> for each change. If it can't be created (no dev database yet, a dev database that would need a reset, a Prisma error) the deploy stops before anything is pushed or uploaded with MIGRATE_FAILED and the way out (ghosty migrate init, then deploy again). --json events: repo-connected, migration-created {name, path, tables}, uploaded {hash, bytes}, building, then {ok, slug, commitSha, appUrl}. | | ghosty preview [name] | Put the current work on a private preview link without touching the live app. Workspace-kept apps upload the folder as the preview preview/<name>; without a name, the folder's last preview is updated. Connects a folder without origin and creates the app's first migration exactly like ghosty deploy (same events and failures). | | ghosty state | Show platform resource status for this app: each part in plain language (PART — "Live service", "Secure credentials (stripe-key)"), its status, and one note (a failure's reason, the repository or app address). --json: {ok, slug, summary, resources}, each resource {kind, label, name?, status, info?, updatedAt?, awaitingFirstMigration?} — kind is the stable machine key, label the words to show a person, name only when it is the app's slug or a secret's own name (internal names are omitted). Three kinds go out under a neutral public key — app.register, build.cache, teardown.builds — never a provider's name. resources lists the app's parts only: records about the app (its code versions, sleep, suspension, a transfer or inactivity notice) are left out, and summary counts the same rows. A failure's info never carries platform internals: the platform's own wording stands in. Raw platform metadata is never emitted (the MCP get_app_state tool returns the same rows; ghosty delete --json's deleting {plan} follows the same rules). | | ghosty dev | Run frontend + backend locally with your personal dev database. When the app has a database and ships migrations (backend/prisma/migrations/), it first applies the ones your dev database doesn't have yet (prisma migrate deploy with the backend's own Prisma — a no-op once up to date), so a fresh copy of an app starts with its tables; --json event {event: "migrated", applied}, MIGRATE_FAILED stops it before the servers start. Warns (never blocks) about each secret the deployed app has but backend/.env.local doesn't. | | ghosty migrate <name> | Apply a database schema change to your personal dev schema (<name> is a short snake_case label). Node apps run Prisma; Python apps run the backend's migrate entrypoint. No-op with a clear message when the app has no database yet. | | ghosty env | List every environment variable this app runs with and who sets it — the platform, one of your secrets, your app config, or the access mode. Secret values are never shown; --json for tooling. | | ghosty secret <name> | Store a secret for this app (kebab-case <name>; --value or hidden prompt), record its name in app.config.json, and bind it to the service as the UPPER_SNAKE_CASE env var. One value per app — the published app and its previews share it. The interactive run also asks for a local value for development (enter to skip; --local-value for scripts) and writes it to backend/.env.local; without one it leaves an empty NAME= stub and ghosty dev reminds you. Values are never echoed. | | ghosty deploys / ghosty logs / ghosty redeploy | Inspect and trigger production deploys. | | ghosty routines | Work your apps do on a schedule: the platform calls a path in the app (never a web address) on a 5-field schedule, in a timezone you choose. list [--app] (without --app: every app you develop), add --name --path --schedule [--timezone] [--timeout], pause / resume / rm <name>, run <name> (Run now — exits non-zero unless the run succeeded) and runs <name> (history). Routines are addressed by name (or id); --app defaults to the app in this folder. The app handles the path with onRoutine() / @on_routine. When your plan no longer allows a routine, the platform pauses it: list marks it [paused by your plan] and says why (pausedReason in --json); resume works again once it fits the plan. An app created before routines gets its helper with setup (run in the app's folder; local files only — then ghosty deploy; --json → {ok, changed, manualSteps, alreadyReady}, exit 2 while steps are left to do by hand). | | ghosty apps outbound-ip <slug> [--on\|--off] | A company workspace's fixed outbound IP: one fixed address every connection an app makes to the internet comes from, so a database, an API or a tunnel can allowlist it. Without a flag it shows whether the app uses it and the address; --on / --off switch it (takes about a minute; open connections reconnect). Workspace owners and admins only. Runs from any folder. --json: {ok, slug, enabled, address, active, waitsForDeploy} — active is whether the app goes out through the address right now (false while a switch is still being applied: wait for true before relying on it), and waitsForDeploy: true means the change applies with the app's next deploy (its live version was pinned by a preview); both are absent on workspaces that don't report them yet. Errors: OUTBOUND_IP_NOT_AVAILABLE (the workspace can't offer it, or not yet), NOT_A_COMPANY_ADMIN, APP_NOT_FOUND, TRANSFER_IN_PROGRESS, APP_DELETING, APP_NOT_READY, OUTBOUND_IP_UNAVAILABLE (try again), OUTBOUND_IP_FAILED, OUTBOUND_IP_UNCONFIRMED (no answer in time — read it again in a minute), CANCELLED (the switch may still apply). | | ghosty design | Print the workspace's design guide, if one is set — pipe it to your coding assistant. | | ghosty profile --github <username> | Record your GitHub username (grants push access on app repos). | | ghosty preflight | Check Node, git, sign-in, and platform reachability. |

Every command supports --json for machine-readable output, and long-running commands end with a single parseable ready/READY line. Interactive prompts only appear on a TTY when a required value is missing — every prompt can be skipped with flags. Works on macOS, Linux, and Windows.

Credentials live in ~/.ghosty/profiles.json (owner-only permissions), one profile per admin URL, so one laptop can talk to multiple companies.

Development

npm run build -w ghosty-cli   # copies templates, then tsup → dist/
npm test -w ghosty-cli        # vitest (no network)
node packages/cli/bin/ghosty.js --help

App templates ship in templates/ (consumed by ghosty init, maintained separately from the command code).