# Getting started

URL: /code/getting-started · Id: `page:code/getting-started`

> Create a Startup as code, add a Noun and an Offer, take a test payment, watch its Events, ship the Change and attach your domain.

`npm create startups` creates a [Startup](/business/nouns/startup) and the project that defines it as code. In about fifteen minutes it takes a test payment on its own preview, and the same files run it live.

```bash
npm create startups
```

## What you build
Leaseline tracks lease renewals for small property managers and sells one plan at $29 a month. By the end it has a `Lease` [Noun](/business/nouns/noun) with its own API and an [Offer](/business/nouns/offer) with a working checkout. It also has a paid test [Subscription](/business/nouns/subscription) and a live address on `leaseline.app`.

You need npm and a terminal. Everything below runs in the test environment, so no real money moves.

## Steps
1. Create the project from the [Solo SaaS](/start/templates/solo-saas) [Startup Template](/business/nouns/startup-template):

   ```bash
   npm create startups leaseline.app -- --template solo-saas --yes
   ```

   ```text
   Created Leaseline in test
     Startup      startup_1
     Template     Solo SaaS
     Interfaces   https://api.sb/leaseline.app · MCP · SDK · CLI
   Next: cd leaseline
   ```

   The Startup runs from the first second, with a [Site](/business/nouns/site), an [App](/business/nouns/app), an API and an agent in every [Role](/business/nouns/role) the Startup Template staffs. The project holds only what differs from it:

   ```text
   leaseline/
   ├── startup.ts       the Startup: name, domain, the Startup Template it extends
   ├── startups.lock    the Startup Template Version it pins
   ├── AGENTS.md        how any coding agent works this Startup
   ├── .mcp.json        the MCP servers, scoped to leaseline.app
   └── package.json
   ```

2. Start the dev server. It watches the project and previews each edit as a [Change](/business/nouns/change):

   ```bash
   cd leaseline
   npx startup-builder dev
   ```

   ```text
   Watching leaseline in test
     Preview   https://preview-4f1c.leaseline.app
     Change    change_1 (no edits yet)
   ```

3. Add a Noun. Leaseline declares a `Lease` Noun in one file:

   ```mdx title="nouns/Lease.mdx"
   ---
   properties:
     unit: string
     resident?: Contact
     endsOn: date
     rent?: money
   verbs:
     renew: { months: integer, increase?: number }
     notify: {}
   ---
   A Lease is one resident's agreement on one unit.
   ```

   The dev server compiles it at once and writes its types to [`.sb/types/`](/code/file-conventions/generated#types-in-the-editor). `$.Lease` is typed, `/app/leases` lists records, and `Lease.renew` is a route, a CLI operation and an MCP tool.

4. Write a first record from code:

   ```ts
   import { $ } from 'startup-builder'

   const lease = await $.Lease.create({ unit: '4B', endsOn: '2027-01-31', rent: { amount: 1800, currency: 'USD' } })
   ```

5. Add the Offer. Its [Price](/business/nouns/price) compiles to a Stripe price and a checkout on the preview:

   ```mdx title="offers/pro.mdx"
   ---
   price: { amount: 29, currency: USD }
   interval: month
   ---
   ```

6. In a second terminal, stream the Startup's new subscriptions:

   ```bash
   npx startup-builder listen Offer.subscribed
   ```

7. Open `/pricing` on the preview, choose the plan and pay with the test card `4242 4242 4242 4242`. The listener prints `Offer.subscribed` with the new Subscription, and the founder's App shows the first $29.

8. Run the checks on the Change the dev server printed. Every test and [Evaluator](/business/nouns/evaluator) runs on the preview:

**Ask**

   ```text
   Review my change.
   ```

**API**

   ```bash
   curl -X POST https://api.sb/leaseline.app/changes/change_1/review \
     -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"
   ```

**SDK**

   ```ts
   import { $ } from 'startup-builder'

   const change = await $.Change.review({ change: 'change_1' })
   ```

**CLI**

   ```bash
   npx startup-builder do Change.review --json '{"change":"change_1"}'
   ```

**MCP**

   ```json
   {
     "name": "do",
     "arguments": { "code": "return await $.Change.review({ change: 'change_1' })" }
   }
   ```

9. Merge it into a new [Version](/business/nouns/version):

   ```bash
   npx startup-builder do Change.merge --json '{"change":"change_1"}'
   ```

   ```text
   Merged change_1
     Version   version_2
   ```

10. Deploy the Version that merge printed. It asks the founder first, then points the live address at the new build:

    ```bash
    npx startup-builder do Version.deploy --json '{"version":"version_2"}'
    ```

11. Attach the [Domain](/business/nouns/domain) to the Startup that step 1 printed. Connect prints the DNS records to set at your registrar and verifies them:

    ```bash
    npx startup-builder do Domain.connect --json '{"hostname":"leaseline.app","startup":"startup_1"}'
    ```

12. Read what you built, own and inherited values side by side:

    ```bash
    npx startup-builder show /
    ```

## Result
Leaseline runs from seven files. The `Lease` Noun has an API, SDK methods, CLI operations and MCP tools.

The Offer sells through a Stripe checkout, and its first test Subscription raised `Offer.subscribed`. The merged Version serves `leaseline.app`, and every later edit ships the same way.

Live charges start once the owners finish Stripe's onboarding ([Stripe](/code/platform/stripe)).

## Next steps
- [Business-as-Code](/business/business-as-code): why seven files are enough.
- [Build with a coding agent](/code/build-with-a-coding-agent): let an agent make the next change.
- [The project structure](/code/project-structure): every folder and file.
- [`startup.ts`](/code/startup-ts): every key of the root file.
- [Platform](/code/platform): the database, auth, storage, functions and realtime underneath.