npx saas.dev
npx saas.dev creates your product, checks and pushes its definition, takes it Live on your domain and connects your Stripe account. It runs without an install, signs in once per machine, and every command answers the same way to you and to your coding agent.
Start a product
init asks for a name, signs you in on the first run, and starts your product from Leaseclock unless --from names another. It writes the definition files and AGENTS.md into a new folder, and prints the address where your copy already runs in Test.
Start building on saas.dev does the same in the browser. Your copy runs at once, and npx saas.dev pull my-product writes its files into a folder when you want them.
$ npx saas.dev init
Name your product: my-product
Signed in as you@example.com
Created my-product in Test from leaseclock.com
Noun/Lease.mdx Noun/Unit.mdx Offer/pro.mdx AGENTS.md
https://my-product.test.saas.devSign in
login opens a browser tab on api.saas.dev, and the CLI keeps an id.org.ai token for the machine, so neither you nor your agent pastes a key.
In CI, set SAAS_DEV_TOKEN to a token from token create, and the CLI reads it from the environment instead of opening a browser. A token pushes to Test unless it was created with --live.
$ npx saas.dev login
Signed in as you@example.com
$ npx saas.dev token create ci
Created the token ci. It pushes to Test.
Store it as SAAS_DEV_TOKEN in your CI secrets.Push and preview
push checks every file in the folder and saves a new version in Test. When files break a rule, nothing is saved, and every error comes back at once with its file, line, fix and edit, so your agent corrects them in one pass. push --fix applies every edit, then previews.
push --preview prints what changes on each surface and saves nothing. push --live serves the version Test runs to your customers once you approve it: it prints an approval link, and Live changes when you open it and approve. Only a token made with token create --live skips the link.
With --json, a push prints { ok, errors } and a preview prints { version, changes: [{ surface, change, breaking }], breaking }.
| Exit code | When |
|---|---|
0 | The command did what it says |
1 | Any error, such as a file that breaks a rule |
2 | A breaking change without --yes |
$ npx saas.dev push
422 Lease.mdx line 6: field "EndsOn" must start lower-case. Rename it to "endsOn".
422 pro.mdx line 4: limits names "Units", and no Noun has that name. Use "Unit".
$ npx saas.dev push --fix
Pushed version 2 · https://my-product.test.saas.dev
$ npx saas.dev push --live
Approve at https://api.saas.dev/approve/v2
Approved by you@example.com · Live serves version 2
Live · https://my-product.saas.devGo live
domain add serves the product on your own domain and prints the one DNS record to add at your DNS host. Test then answers at test. on the same domain.
stripe connect signs you in to Stripe once, for Test and Live. Payments land in your Stripe account, under your product's name. Stripe covers checkout, the billing portal and refunds.
$ npx saas.dev domain add leaseclock.com
Add this record at your DNS host: CNAME leaseclock.com leaseclock.saas.dev
✓ leaseclock.com answers, with its certificate
$ npx saas.dev stripe connect
✓ Stripe connected · acct ••••7c1eVersions and export
Every push is a version. versions lists them with who pushed each and where it runs, pull writes any of them into the folder, and rollback serves an earlier one again as a new version. pull also writes .saas/types.d.ts, so an override that names a renamed field fails to type-check.
export downloads the definition and every record in one file. Your Stripe account and your domain stay yours.
$ npx saas.dev versions
19 you@example.com Oct 21 Test
18 you@example.com Oct 14 Test, Live
$ npx saas.dev rollback 18 --live
Live serves version 18.
$ npx saas.dev export
Saved leaseclock.com-2026-10-25.jsonCommands
| Command | What it does |
|---|---|
npx saas.dev init [folder] [--from <domain>] | Asks for a name, signs you in on first run, starts from Leaseclock unless --from names another product, writes its files and AGENTS.md, and prints its Test URL |
npx saas.dev login | Signs you in through the browser and stores an id.org.ai token |
npx saas.dev pull [name] [version] | Writes a product's definition, or an earlier version, into a folder, with .saas/types.d.ts and .saas/schema/ |
npx saas.dev push | Checks every file and pushes a new version to Test |
npx saas.dev push --preview | Checks every file and prints what changes on each surface, saving nothing |
npx saas.dev push --live | Pushes the version in Test to Live, after a preview |
npx saas.dev versions | Lists every version with who pushed it and where it runs |
npx saas.dev rollback <version> [--live] | Serves an earlier version again, as a new version |
npx saas.dev open [path] | Opens the product in Test in the browser |
npx saas.dev domain add <domain> | Serves the product on your own domain, with the DNS record to add |
npx saas.dev stripe connect | Connects your Stripe account, once, for Test and Live |
npx saas.dev token create <name> [--live] | Creates a token for CI, which pushes to Test unless created with --live |
npx saas.dev token revoke <name> | Ends a token |
npx saas.dev export | Downloads the definition and every record in one file |
npx saas.dev mcp | Serves SaaS.Dev's MCP tools over stdio, for an agent on this machine |
| Flag | What it does |
|---|---|
--yes | Confirms without a prompt, for scripts and CI |
--json | Prints the result as JSON: a push returns { ok, errors }, a preview { version, changes, breaking } |
--fix | Applies every error's edit, then previews |
--product <domain> | Picks the product when the folder does not say |
Questions
How is it different from npx leaseclock
npx saas.dev is yours: it builds and ships the product. npx leaseclock is the product's own CLI, generated from your definition for your team and your customers to read records and run Verbs. Nothing in it names SaaS.Dev.
Does my agent run these commands
Yes. Your agent runs the same commands with your sign-in, reads the same previews and errors, and fixes a file from the line and the fix each error names. Live still waits for you: push --live hands your agent an approval link to send you. Build with your agent connects it.