BTSBTS
Now in public beta

A live preview URL for every branch you push

BTS turns every git branch into a running copy of your app — complete with its own Postgres, Redis, and storage — in under 60 seconds. Stop sharing one staging server. Start reviewing real working software on every pull request.

Connect a repo · Live URL in under a minute

terminal
$ git push origin feature/new-checkout

  [nexos]  webhook received
  [nexos]  building image on node eu-west-2
  [nexos]  provisioning postgres · redis · s3
  [nexos]  restoring seed (v3-with-orders)  4.2 MB
  [nexos]  container started  ·  health check passed

  preview → https://feature-new-checkout-acme.test.buildingswell.com
  ready in 47s
< 60s
git push to live URL
Hard quotas
vCPU · vRAM · build minutes
AES-256
encrypted secrets at rest
Bring your own
compute · self-hostable
Why this matters

Shipping software without preview URLs is a tax on your team

Most teams know they should have previews. Most teams do not, because the tooling makes it painful. Here is what that costs:

Waiting on staging

Your team shares one staging server. Every code review blocks on the last person who deployed — and nobody tested their branch in isolation.

Preview URLs cost a fortune

Spinning up a full stack on AWS for every pull request burns thousands of dollars a month on idle compute. Most teams give up and ship blind.

Databases reset on every push

You set up test data, find a bug, push a fix — and watch your seed wipe everything. Preview environments are unusable without persistent data.

What is BTS

Preview environments that actually act like production

A preview environment is a full, running copy of your application — not a static build, not a frontend-only deploy, but the actual stack. Your app container, your database with seeded data, your cache, your object storage — all wired together at a URL you can share.

BTS gives every git branch its own preview environment, automatically, the moment you push. No pipelines to author. No Kubernetes manifests to maintain. A webhook fires, a container starts, a URL goes live.

And because capacity is governed by fixed vCPU, vRAM, and build-minute ceilings rather than a meter, full-stack previews cost a fraction of what they do on AWS or GCP. You can afford one per branch, not one per team.

How it works

From git push to live URL in three steps

You write code. BTS does the rest.

Step 1

Push to a branch

A GitHub webhook fires the moment you push. No CLI, no YAML pipelines, no extra config.

Step 2

We build and provision

The scheduler picks a node with free capacity. BuildKit builds your image. Postgres, Redis, and storage come up in parallel.

Step 3

Share the URL

Drop the preview link into a PR or Slack. Reviewers, designers, and QA all click through the real app — live data and all.

Setup

No DevOps. No pipelines. No infra to maintain.

Spinning up a BTS project is one config file — nexos.yaml at the root of your repo. It captures your Dockerfile, your port, the services you need, and your migrations. BTS reads it on every push and does the rest.

Don't want to write it yourself? Hand your AI assistant this link — test.buildingswell.com/docs/nexos-yaml/ai — and ask it to configure the project. The page is a self-contained spec written for AI agents. They detect your stack, generate the YAML, and (when your existing Dockerfile isn't preview-ready) create a Dockerfile.nexos that meets our requirements.

nexos.yaml
name: my-app

build:
  dockerfile: ./Dockerfile

app:
  port: 3000

services:
  postgres: true
  redis: true

hooks:
  on_deploy: npx prisma migrate deploy

Commit it. Push. You have a preview URL.

terminal
$ git commit -am "tweak checkout" && git push

  [nexos]  fetching delta → feature/new-checkout
  [nexos]  web changed · rebuilding
  [nexos]  api, worker, migrations untouched · skipped
  ready in 14s

  preview → https://feature-new-checkout-acme.test.buildingswell.com
Incremental deploys

A loop fast enough for humans — and AI agents

Every node keeps a persistent mirror of your repo, so a push fetches only the new commits — never a full clone — and BTS diffs the push to rebuild only what changed. Services whose files are untouched keep their running containers, and migrations re-run only when their files change.

Iteration time drops from minutes to seconds. That makes BTS the natural target for AI coding agents: point one at a live, full-stack environment with a real database and let it iterate with fast feedback — not against mocks.

  • Incremental git fetches — persistent per-node mirrors, no full clones
  • Unchanged services skip the rebuild — their containers keep serving
  • Migrations re-run only when their files change
  • Real Postgres, Redis, and storage, persisted across deploys
Use cases

What you do with a URL per branch

Preview environments unlock workflows that are impossible with a single shared staging server.

Pull request reviews

Every PR gets a URL. Reviewers click through working changes instead of squinting at diffs.

Bug reproduction

Reproduce a customer bug on their exact seed data, fix it on a branch, share the fixed URL back.

Designer handoff

Designers see the real app on the real data, not a Figma mock. Feedback lands in hours, not sprints.

QA verification

QA sets up a test scenario once and verifies fixes across every subsequent push — data persists.

AI coding agents

Point an agent at a live, full-stack environment and let it iterate against a real database — not a mock.

Product demos

Show a WIP feature to stakeholders from a branch URL. Throw the environment away when you are done.

What you get

Everything a real preview environment needs

Not a static build. Not a frontend-only deploy. The full stack.

60-second deploys

Push to any branch. A live URL with your app, database, and storage is ready before you can finish your coffee.

Full-stack previews

Every branch gets its own Postgres, Redis, and any managed addon you enable — wired up automatically to your app container.

Persistent databases

Incremental deploys rebuild only your app container. Your data, user sessions, and test state survive every push.

Encrypted secrets

Environment variables are AES-256-GCM encrypted at rest with per-value initialization vectors. Never stored in plaintext.

Predictable resource ceilings

Every workspace carries hard vCPU, vRAM, and build-minute quotas. Hit a cap and deploys pause instead of quietly eating the whole node.

Live build logs

Stream BuildKit output and container logs into your dashboard over WebSocket. See exactly what is happening as it happens.

FAQ

Questions, answered

The things teams ask before their first deploy.

What can I deploy on BTS?

Anything with a Dockerfile — Node, Python, Go, Rails, Elixir, you name it. No framework lock-in. Multi-service projects (app plus background workers, plus Postgres and Redis) work too.

Do my databases really persist across pushes?

Yes. Incremental deploys rebuild only the app container. Your Postgres, Redis, and object storage survive every push until you reset or destroy the environment — so test data and sessions stick around.

How do database migrations run?

Declare them as hooks in nexos.yaml (for example, on_deploy: npx prisma migrate deploy). They run automatically on each deploy. Migration jobs re-run only when their files actually change — unrelated pushes skip them.

Can I bring my own compute or self-host?

Yes. The node agent is a single Go binary you run on any server — join the shared global pool or keep nodes private to your team. The control plane and agent are open, so you are never locked in.

Still have a question? Email us or read the docs.

Give every branch its own URL

Connect a GitHub repo, push a commit, share the link. That is the whole workflow.

Connect a repo and ship your first preview

Get the BTS newsletter

Product updates, preview-environment tips, and the occasional deep dive. One email a month. No spam, unsubscribe anytime.