DocsPricingBlogChangelog
Examples use: Lease

Every code example, in your word.

Sign inStart building

Quickstart

Open

Your own product goes live in six steps: sign in, start from Leaseclock, read its three files, buy its plan with Stripe's test card, make it yours, and go live on your domain with your own Stripe account.

Leaseclock tracks lease renewals for property managers, and it runs at leaseclock.com. You start from a copy of it at my-product.test.saas.dev, and you finish with your own product on your own domain, taking payments into your own Stripe account.

With your agent

Paste this into your coding agent, then follow the six steps to see what it does:

Prompt
Read https://saas.dev/llms.txt. Then start my product on SaaS.Dev in this
folder: sign me in with `npx saas.dev login`, run
`npx saas.dev init my-product --from leaseclock.com`, rename Lease to what my
product tracks, [what your product keeps], push to Test with
`npx saas.dev push`, fix every error it names, open the pricing page so I can
buy the plan with Stripe's test card, then connect my Stripe account and push
to Live when I say so.

You need Node.js 20 or later, an empty folder and, for the prompt, a coding agent that runs terminal commands, such as Claude Code or Cursor. Your first product is free, and nothing in Test charges a real card. Every command is on the npx saas.dev page.

Sign in

Terminal
$ npx saas.dev login
Signed in as you@example.com

A browser tab opens on api.saas.dev, and you approve the sign-in there. The CLI keeps an id.org.ai token for this machine, so neither you nor your agent pastes a key. In CI, set SAAS_DEV_TOKEN in the environment and the CLI uses it instead of opening a browser.

Start from Leaseclock

Terminal
$ npx saas.dev init my-product --from leaseclock.com
Created my-product in Test from leaseclock.com
  Noun/Lease.mdx  Noun/Unit.mdx  Offer/pro.mdx
  https://my-product.test.saas.dev

The folder my-product/ now holds Leaseclock's three files, and my-product.test.saas.dev already runs them, starting with Leaseclock's Test records: sign-in, the admin, the API, docs, a home page and a pricing page.

The App your copy runs at my-product.test.saas.dev, with Leaseclock's Test records: Northgate Rentals and its six leases.

Test is a full copy of the product with its own records and Stripe's test mode, so nothing in it charges a card or emails a real customer. It answers at my-product.test.saas.dev until you add your own domain.

Read the three files

Leaseclock keeps two things: Units, the apartments a property manager rents out, and Leases, which tie a renter to a Unit until a date. Each is a Noun. A Lease can be renewed or ended, and those are its Verbs.

Noun/Lease.mdx
---
name: Lease
fields:
  unit: { type: link, target: Unit, required: true }
  renter: { type: email, required: true }
  endsOn: { type: date, required: true, indexed: true }
  status: { type: choice, options: [{ key: active }, { key: ended }] }
verbs:
  renew:
    does: Move the end date forward
    input: { endsOn: { says: the new end date, type: date, required: true } }
    from: [active]
  end: { does: End the lease, from: [active], to: ended }
---

renew has no function, so it does what it declares: it writes the new endsOn onto the lease. The plan customers buy is an Offer, Leaseclock Pro, at $29 a month for up to 200 Units.

Noun/Unit.mdx and Offer/pro.mdx
Noun/Unit.mdx
---
name: Unit
fields:
  label: { type: text, required: true }
  building: { type: text }
---
Offer/pro.mdx
---
name: Leaseclock Pro
price: { amount: 29, currency: USD, unit: month }
limits: { Unit: 200 }
personas: Property manager, Leasing coordinator
status: Live
---

These three files are the whole definition. Open my-product.test.saas.dev: the admin lists Units and Leases with a Renew button on each active Lease, /docs/lease explains both Verbs, and /pricing sells Leaseclock Pro.

Buy Leaseclock Pro in Test

Terminal
$ npx saas.dev open /pricing
Opened https://my-product.test.saas.dev/pricing

Press Subscribe on Leaseclock Pro. Stripe Checkout opens under Leaseclock's name, in Leaseclock's teal. Check out as Priya Shah of Northgate Rentals, with Stripe's test card:

FieldValue
Emailpriya@northgaterentals.com
Card number4242 4242 4242 4242
ExpiryAny future date, such as 12/28
CVCAny three digits

Checkout returns Priya to the app, signed in to Northgate Rentals' workspace, which holds up to 200 Units. The subscription shows on the admin's Billing screen, and Priya's billing portal lists the paid invoice.

In Test, checkout runs on a Stripe test account that SaaS.Dev opens for your product, so the purchase needs no Stripe account of your own.

Make it yours

Rename Lease to what your product keeps, change a field, and push. Here the product books appointments: rename Noun/Lease.mdx to Noun/Booking.mdx, change name: Lease to name: Booking and endsOn to startsAt, and name the plan Booking Pro in Offer/pro.mdx.

Terminal
$ npx saas.dev push
my-product · Test

  ~ Lease → Booking          /app/leases → /app/bookings · $.Lease → $.Booking
  ~ endsOn → startsAt        every screen, the API, the SDK and the docs
  ~ Leaseclock Pro → Booking Pro   the pricing page and the Stripe product

Push these changes to Test? (y/N) y
Pushed version 2 · https://my-product.test.saas.dev

SaaS.Dev shows the change on every surface and waits for a yes before it saves anything.

When a file is wrong

Every file is checked before anything is saved. An error names the file, the line and the fix:

422  Lease.mdx line 6: field "EndsOn" must start lower-case. Rename it to "endsOn".

Test stays as it was until the push passes. Your agent reads the line, fixes it and pushes again. Every code and its fix is in Errors.

Go live

Add your domain, connect your Stripe account and push to Live:

Terminal
$ npx saas.dev domain add bookings.example.com
Add this record at your DNS host:  CNAME  bookings.example.com  my-product.saas.dev
✓ bookings.example.com answers, with its certificate

$ npx saas.dev stripe connect
✓ Stripe connected · acct ending 4f2a

$ npx saas.dev push --live
Push version 2 to Live? (y/N) y
Live · https://bookings.example.com · Stripe: connected (acct ending 4f2a) · Booking Pro sells at $29 a month

Your product now answers at bookings.example.com, and Test moves to test.bookings.example.com. When a customer subscribes to Booking Pro, Stripe Checkout charges their card in Live and the payment lands in your Stripe account, under your product's name. It shows on the admin's Billing screen as Paid, and Stripe pays it out to your bank. SaaS.Dev takes no share of it.

Next

  • Errors: every error code, with its cause and fix.
  • Nouns and Verbs: describe what your own product keeps and what people do to it.
  • Stripe: refunds, trials, taxes and what your customers see.
  • Defaults and overrides: change the theme, or replace a screen with your own React component.

Contents