filed under labs

Everything around your app. Picked and wired.

Every new product needs sign-in, payments, email, flags, storage, jobs and an admin panel before it needs anything of its own. Groundwork picks them for what you are building, tells you where each free tier actually stops, and ships them already wired to each other.

Request access See how it works
The picked stack nine jobs, one service each, provisioned and connected on project creation

2 100users

Where this picked stack's first paid tier begins, read from the vendors' own limits rather than their pricing pages.

9services wired to each other, not nine tabs of documentation
0lines of glue to write between them
Sign-in
Clerk
10 000 monthly active users
alternative: Auth0, Supabase Auth
Billing
Stripe
no platform fee, no customer ceiling
alternative: Paddle, Lemon Squeezy
Email
Resend
3 000 emails a month, 100 a day
alternative: Postmark, Amazon SES
Feature flags
PostHog Flags
1 000 000 flag requests a month
alternative: Flagsmith, Unleash
File storage
Cloudflare R2
10 GB stored, no egress charge
alternative: Backblaze B2, Supabase Storage
Background jobs
Upstash QStash
500 messages a day
alternative: Inngest, Trigger.dev
Admin panel
Ships in the kit
no seat ceiling, runs in your project
alternative: Retool, Forest Admin
Status page
Better Stack
10 monitors, 1 public status page
alternative: Instatus, Uptime Kuma
Analytics
PostHog
1 000 000 events a month
alternative: Plausible, Fathom
@groundwork/kit

One typed SDK over all nine, with the credentials generated at bootstrap and kept out of the repository.

Example values from one picked stack. Each vendor's real numbers live on its directory page, kept to the same figures as the picker.


The problem

The plumbing is the same every time and it is rebuilt every time

A new product needs sign-in, a way to take money, transactional email, feature flags, file storage, background jobs, an admin panel, a status page and analytics before it needs anything of its own. Each has a good vendor and most have a free tier. Choosing between them is a week of reading pricing pages that hide the limit that matters.

The cost after choosing is the wiring. When a customer upgrades, the payment provider's webhook has to update the plan, the flag service has to unlock the feature, the email service has to send the receipt, the analytics event has to fire and the admin panel has to show it. That is a week of glue per founder, written under time pressure and never tested for the failure in the middle.

The lists of free tiers that exist are lists. They do not know what is being built, they do not say where a tier stops for that shape of product, and they stop at the link. The picker and the kit start there.


How it works

Pick, see the limits, take the wiring

01

Describe the product

A short form, or a paste of the README: what it does, who pays, roughly how many users at launch. Nothing stored, the way every tool in the toolbox works.

02

Get the stack

One service per job, with the free tier's real ceiling for this product, the first paid step and what it costs, and the alternative for each slot. A directory page per service carries the same numbers, kept current, so the picker and the directory never disagree.

03

Take the kit

A licensed starter kit with the picked services already wired: the credentials generated at bootstrap and kept out of the repository the way Paved bootstraps a tenant, the events already flowing between the services, and one typed SDK over all of them.

04

Ship

plan.upgraded flips the flags, sends the receipt, fires the analytics event and appears in the admin panel without a line of glue. Every service stays a standard one underneath, so leaving is a config change.


The wiring

The wiring is the product

Each of the nine services is good on its own, and choosing them is the easy half. What costs a week under time pressure is how they talk to each other when a customer upgrades. That part ships as code, written once instead of once per project, with the order and the retries between the steps already handled.

// The kit, after the picker chose Clerk, Stripe, Resend, PostHog and a Postgres.
import { groundwork } from "@groundwork/kit";

const app = groundwork({ project: "acme" });

// One call. Billing, flags, email, analytics and the admin panel
// react to the same event, in order, with retries between them.
await app.plans.upgrade({ user: user.id, to: "pro" });

// What ran, in the order it ran, as the admin panel shows it:
//   billing.subscription.updated   sub_… → pro
//   flags.set                      pro features for user
//   email.sent                     receipt, template pro-upgrade
//   analytics.track                plan_upgraded
//   admin.timeline                 "upgraded to pro" on the user's page

One call, five services, in order

  1. billing.subscription.updatedThe payment provider confirms the subscription and the plan on the record changes.
  2. flags.setThe paid features unlock for that user alone, not for the whole project.
  3. email.sentThe receipt goes out on the upgrade template, once, with the retry owned by the kit.
  4. analytics.trackThe event lands in the analytics service under a name the funnel already expects.
  5. admin.timelineThe whole chain appears on the user's page, so support can read what happened without a log search.

Example output. The comment block is what the admin panel shows for the same event.


Scope

What Groundwork is, and what it is not

What it is

The services around the app, chosen and connected

A free picker that turns a description of the product into one service per job, each with the free tier's real ceiling, and a licensed starter kit where those services arrive wired to each other. The code lives in your repository, on whatever host was already chosen.

What it is not

Not a hosting platform, not a backend service, not a framework

Nothing is hosted here and nothing is resold. Every service in the stack is a standard account in your name, billed by the vendor, and the wiring ships as code rather than as a runtime to sit inside. The kit fits the framework already picked; it does not replace it.


Who it is for

People building alone, and the agencies that do it for them

Solo

The technical founder shipping alone

Knows how to build the product and has no time to evaluate nine vendors or write the glue between them a third time.

Repeatable

The agency launching a client's product

Does this once per client. A picked stack per client, one kit, one set of wiring that has already been tested for the failure in the middle.


What it costs

The picker is free; the kit is licensed once

The picker and the directory are free, the way the rest of the toolbox is. The kit is a one-off licence per project, with the wiring as code you own afterwards. Vendor usage is billed by the vendors, at their prices, and any referral commission on those links is stated on the directory page that carries it.

Picker and directory

Free, with nothing behind a sign-in

Describe the product, read the ceilings, follow the links. No account to open before the answer appears.

Starter kit

A one-off licence per project

Paid once, not monthly. The wiring ships as code in your repository, under a licence that lets you keep it after the project ends.

Vendor usage

Billed by the vendors, at their prices

Each service is a standard account in your name. Nothing is resold, and nothing sits between you and the vendor's own bill.

Referrals

Stated where it applies

Where a directory link carries a referral commission, that page says so. A commission never moves a service up the picker's answer.


Request access

Say what you are building

Requests decide which services the first kit wires.

Free for the whole beta. The first twenty-five teams keep 50% off for twelve months after launch, locked in at signup.

Your address is used for this request and nothing else. One email when there is something to show.


Objections

Reasonable objections

Supabase or Firebase already do this.
They give a database, auth and storage, well, and stop there. Billing, email, flags, the admin panel and the wiring between them are still assembled by hand. The picker will often choose one of them for its slot, and the kit starts where they stop.
free-for.dev already lists the free tiers.
It lists them, thoroughly, for everyone. It does not know what is being built, it does not say where a tier stops for that product, and it ends at the link. The picker answers for one product; the kit is what happens after the link.
A starter kit is a lock-in.
Every service in it is a standard vendor, every table and every event is exportable, and the wiring ships as code in your repository under a licence that lets you keep it. Leaving means keeping what you have.