Early access, by invitation

Every branch gets its own app, database and URL. One command.

Your agent runs karts up. The branch boots in its own micro-VM with a migrated, seeded copy of your database. Agents on different branches never share a database.

tiny-shop · feature/refundsup in 2.23 s
$ karts up ✓ 1 new migration (0011_create_refunds.sql): numbers claimed ✓ revision 1 ready: database cloned from main's template, 1 new migration applied, nothing destructive found feature-refunds-fc00 https://feature-refunds-fc00.karts.kartikey.fyi (public; seed data only) $ karts down ✓ feature-refunds-fc00 is gone (its database and VM are destroyed; migration-number claims are kept)

Works with

  • Claude Code
  • Codex
  • Cursor
  • Any shell

Agents on one database break each other's work. Give each branch its own.

Today

  1. 01Every branch uses the same staging database.
  2. 02Two branches add migration 0011. You find out after the merge.
  3. 03A DROP COLUMN hits the shared database before anyone reads it.
  4. 04The preview's database is empty, or points at production.

With Karts

  1. Each branch gets its own database, in its own VM.
  2. The second 0011 is refused, with the next free number.
  3. Destructive migrations wait for --allow-destructive.
  4. Every copy starts from main's migrations and seed.

One command per branch. Nothing shared.

  1. feature/refunds adds 0011_create_refunds.sql; number checked and claimed
  2. upload only the files the server doesn't have
  3. template clone copy of main's database disks 1 ms
  4. micro-VM restored from a snapshot; 0011 applied restore 16 msclone_init 112 msfiles 8 msmigrations 230 ms
  5. public URL feature-refunds-fc00.karts.kartikey.fyi ready 881 ms
Tiny Shop, feature/refunds, 27 Sep 2026 CLI wall time 2.3 s · server build 1.26 s
  1. 01

    karts up

    Claims the branch's migration numbers.

  2. 02

    Clone

    Copies main's database. Applies the branch's migrations.

  3. 03

    Serve

    Boots your app in a micro-VM. Prints the URL.

  4. 04

    karts down

    Destroys the VM and its database.

What karts up does. Real output, not mockups.

Migration numbers, claimed.

Two branches added 0011. The second was refused before it ran:

$ karts up   # feature/discounts
karts: migration 0011 is already taken by branch feature/refunds; renumber to 0012 or later

Dropped columns, stopped.

Refused until you pass --allow-destructive:

$ karts up   # feature/cleanup
karts: destructive migration refused … ALTER TABLE customers DROP COLUMN notes — drops column customers.notes and every value in it

Its own Postgres.

Main's 10 migrations and seed built a template once, in 26.4 s. The next branch got its own copy, migrated, in 1.26 s.

A VM, not a container.

Each branch is a Firecracker micro-VM. It restores from a snapshot in 10.7 ms (median of 100).

What is isolated today

Your agent sets it up.

Tell it: read https://drivekarts.si/onboard.md. It writes karts.yml, runs karts up and fixes what fails.

$ claude mcp add karts -- karts mcp

Test sign-in, email and payments. Nothing real involved.

List the outside services your app uses. Each branch gets stand-ins that answer like the real ones, in the cloud or on your Mac. They never call the real service, and they keep a record of what your app sent.

Email

Mail sent through SendGrid, Resend, Postmark, Mailgun or the Gmail API lands in the branch's test inbox.

Sign-in

“Sign in with Google” or GitHub shows a test sign-in page with test users. Agents can sign in without a browser.

Payments

A Stripe stand-in: checkout, test cards (declines too), subscriptions and refunds. Your app gets signed webhooks.

Any other API

Give it canned answers. A call nothing answers is caught, and the reply has the exact lines to add.

# karts.yml
mail: true   # the test inbox
fakes: [sendgrid, google-login, stripe]
$ karts fakes calls   # what your app sent, secrets removed

Some sign-in libraries need one line changed. How to set it up, and the limits

More than karts up. What else it does today.

Copy a running app.

karts fork copies an app while it runs, with its memory and its data. The app pauses for about 0.1 s (66 ms to 134 ms, median 82 ms). Then each copy goes its own way.

$ karts fork

Secrets, per branch.

Set a key once. Each branch can have its own value. Your app gets it, the logs show ‹secret›, and it is stored encrypted.

$ karts secret set STRIPE_KEY

Real data, masked.

Runs on your machine. It reads your Postgres database without changing it, and swaps emails, names and other personal data for fakes. Links between tables still work. Only the masked copy is uploaded, and it is stored encrypted.

$ karts db snapshot

MySQL and SQLite too.

Not only Postgres. Each branch gets its own MySQL 8.4 or SQLite database. A MySQL branch was up in 4.8 s, a SQLite branch in 2.05 s.

database: mysql   # karts.yml

Static sites, no server.

Point Karts at your built folder and it serves it, with single-page app routing if you ask. You write no server.

kind: static   # karts.yml

Tell us what broke.

When Karts fails, your agent can send us a short report. It shows you the report and asks first. Keys and passwords it can spot are removed before it is stored.

$ karts report

On your own Mac.

The same karts.yml, with no account and nothing uploaded. Each branch gets its own database and a URL that stays the same. A repeat karts up --local keeps the rows you made and runs only new migrations. A front end in one repository finds its API in another. Needs Docker Desktop.

$ karts up --local
http://<branch>.<project>.localhost:7400

2.2 s

from karts up to a public URL

Tiny Shop, one new migration, through the public API: 2.23 s on 28 Sep 2026, 2.59 s on 29 Sep 2026. First build, template included: 8.7 s to 13.7 s. Bigger installs take minutes.

How we measured

Start with one repository.

Bring a web app that uses Postgres, MySQL or SQLite.

Free during early access

  • The karts CLI and karts mcp
  • A micro-VM and a database for each branch
  • Migration-number claims and destructive-change checks
  • Logs and karts exec in every environment
  • karts fork, secrets and masked copies of real data
  • Fake email, sign-in and Stripe for each branch
  • karts up --local on your own Mac

FAQ

More in the docs FAQ.

What runs in the VM?

One Firecracker micro-VM: 2 vCPU and 2 GB of memory unless you ask for up to 4 and 8 GB. It holds your branch's files, your app (up to eight processes, with Redis, a mail catcher and an S3 bucket if you ask) and its own database: Postgres, MySQL or SQLite. The build can reach the npm, PyPI, Go, RubyGems and Packagist registries, GitHub and a few download hosts. Your running app reaches nothing outside the VM unless your karts.yml turns on internet access. The VM in detail.

Can I put real data in it?

Not raw data. Environment URLs are public, with no sign-in, so anyone with the link can open the app. Use seed data, or a masked copy: karts db snapshot swaps personal data for fakes on your machine, and only the masked file is uploaded. Keep keys out of the repository with karts secret set. What to put in it.

Is my code on your servers?

Yes. karts up uploads the working tree, never .git/. What we store and how it is isolated.

Does it catch every bad migration?

No. The destructive check is rule-based: it catches dropped tables and columns and common data-wiping statements, not every one. Keep reviewing migrations.

Which stacks work?

Web apps on Postgres, MySQL 8.4 or SQLite, in Node, Python, Go, Ruby or PHP, with numbered SQL migrations or your own tool (Prisma, Knex, Django, Alembic, Rails). On 29–30 Sep 2026, 19 of 20 open-source apps ran on Karts: 18 with only a karts.yml, and one with one more step. What stops the last one.

Can I run it on my own machine?

On your Mac, yes: karts up --local runs the same karts.yml with no account and no upload. It needs Docker Desktop. On your own servers, not yet as a product: talk to us.

One branch, one app, one database. For every agent you run.

Early access is by invitation. New teams get environments once preview URLs move to their own domain.