Library / SDK
FlareStarter/flarestarter avatar
FlareStarter/flarestarter

FlareStarter: a TanStack Start and Cloudflare Workers SaaS starter that ships working features

A full-stack, edge-native SaaS starter built with TanStack Start and Cloudflare Workers.

398 stars70 forksTypeScriptApache-2.0

At a glance

What is it?
FlareStarter is a fork-ready SaaS template built on TanStack Start, Cloudflare Workers, D1 and KV, with auth, Stripe billing, email, i18n and an admin console already wired. The interesting part is what the repository refuses to include: mocks and placeholder modules.
Who is it for?
Adopt FlareStarter if your product fits Cloudflare Workers, D1 and R2 and you want auth, billing and email already wired rather than assembled from five libraries. Skip it if you need Postgres, long-running background jobs, or a stack you can host outside Cloudflare, because the D1 binding and workerd runtime are load-bearing here.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 65 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 11, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Who FlareStarter is built for, and the work it removes

The README frames the project as a starter that "ships only what actually works" and lists auth, billing, email, i18n, SEO and an admin console as wired features. Read that as a claim about scope rather than quality: the repository is a vertical slice of a commercial SaaS, and the features it includes are the ones every paid product needs before it can charge anyone.

The target user is a small team or solo developer who has already chosen Cloudflare Workers and does not want to spend the first two weeks rebuilding signup, subscription state and a password reset flow. The repository layout supports that reading. There is a drizzle/ directory for schema and migrations, a scripts/ directory with seed SQL, an e2e/ directory with Playwright tests, and a wrangler.example.jsonc that you copy to your own config. That is the shape of a template meant to be forked once and then owned, not a library you upgrade.

The gap it addresses is real. A TanStack Start application on Workers has no batteries: routing and rendering come from the framework, and everything else, including how sessions are stored and where subscription state lives, is your decision. FlareStarter makes those decisions for you and documents them per feature.

How the pieces fit: D1 as source of truth, KV and R2 at the edges

The data path runs through Cloudflare bindings rather than a connection pool. Sessions, users, subscriptions and feedback live in D1, a SQLite-based database, and the README states that sessions use D1 as the source of truth with a cookie cache in front. That is a specific trade-off worth understanding: reads hit the cookie first, and D1 is consulted when the cache cannot answer, which keeps the hot path cheap but means revocation depends on cache expiry as much as on the database row.

Drizzle ORM sits between the schema and the application, and the README describes "one TypeScript chain from the database (Drizzle) to the frontend (TanStack Start)". In practice that means the types you get in a route loader come from the same definitions that generated the migrations, so a column rename surfaces at typecheck time. The package.json exposes the migration commands as scripts rather than leaving them to memory.

Object storage is R2, and the README is explicit that R2 is not public, so avatar uploads are streamed back through a serving route. Locally, storage works through miniflare with no configuration. Email goes through Resend using string templates, and the README gives a concrete reason for that choice: React Email is not usable on workerd. When the Resend API key is missing, emails are captured to the console instead of throwing, which is the kind of decision that keeps local development unblocked.

Billing is Stripe. Subscriptions are monthly or yearly, there is also a one-time lifetime purchase, and webhook handling is described as idempotent. Failed renewals surface an in-app banner asking the user to update their payment method, and the README states plainly that retry emails are left to Stripe rather than implemented in the app. That is a boundary, not an oversight, and it is documented as one.

Installing FlareStarter and getting a first route to render

The repository uses pnpm, pinned to [email protected] in package.json. There are no published install steps in the README beyond the scripts, so the sequence below is the one the script names imply: install dependencies, generate the Drizzle migrations, apply them to a local D1 database, seed it, and start the dev server.

bash
pnpm install
pnpm db:migrate:local
pnpm db:seed:local
pnpm dev

The postinstall hook runs fumadocs-mdx, which is why the typecheck script also runs it first. The dev server listens on port 3000, set by the dev script itself. If you prefer a clean slate, db:reset:local deletes the local D1 state directory and reruns both migration and seed in one step.

bash
pnpm db:reset:local

Configuration comes from a template file. Copy wrangler.example.jsonc to wrangler.jsonc and fill in the bindings and environment variables your deployment needs; the example file is the authoritative list, not this article. For local secrets, the repository ships .dev.vars.example, which is the file Wrangler reads for local development values such as the Stripe and Resend keys.

Deployment is split by environment. The package.json defines two scripts, and each one builds with a CLOUDFLARE_ENV value before calling wrangler deploy.

bash
pnpm deploy:staging
pnpm deploy:prod

Remote migrations follow the same split, with separate database names for staging and production. Note the naming: flarestarter-db-staging and flarestarter-db-prod, applied with --remote. Running the production migration command against the wrong database name is the kind of mistake the separate names are there to prevent.

The Cloudflare lock-in is the design, not an accident

FlareStarter cannot be moved off Cloudflare by changing a connection string. Sessions are stored in D1, file uploads go to R2, and the runtime is workerd, which the README cites as the reason React Email is not used for templates. If your team standardizes on Postgres, or needs a queue worker that runs longer than a request, this template is the wrong starting point and adapting it costs more than starting from a framework template.

There is a second, quieter limitation. The README describes the stack as "free-to-cheap" and built around Cloudflare's free tiers, which is an accurate description of the entry cost but not a capacity plan. A starter cannot tell you where D1 write throughput or Workers CPU limits will bite your particular product. Nothing in the repository claims otherwise, and the docs are silent on load characteristics, so treat scaling as work you still have to do.

The feature set also stops at a specific line. Failed-renewal retry emails are delegated to Stripe. The sponsor page is described as a pure donation loop that unlocks nothing and leaves entitlements untouched, which is a deliberate separation from the billing plan logic. If you need dunning sequences or entitlement changes driven by donations, you are writing them.

FlareStarter compared with a general-purpose SaaS boilerplate

The obvious alternative is a framework-agnostic SaaS boilerplate, typically Next.js with a hosted Postgres database and an ORM such as Prisma. The difference is not the feature list, which overlaps heavily (auth, Stripe, email, admin), but where the code runs and what that forces.

A Next.js boilerplate usually assumes a Node server and a database you can reach over TCP. That gives you long-running jobs, a mature migration story, and hosting choices. FlareStarter assumes the opposite: short-lived requests at the edge, a SQLite database bound to the worker, and no TCP connection to manage. You give up background processing and database portability, and you get a deployment where the compute and the data live in the same place.

The second difference is the type chain. Because Drizzle generates the schema types and TanStack Start consumes them, the boilerplate's value is partly in the compiler. A Next.js starter with a separately typed API layer does not give you that, and teams that have been burned by drift between an ORM model and a hand-written response type will notice the difference immediately.

A third alternative is to skip the starter entirely and assemble better-auth, Drizzle and Stripe yourself. That is a legitimate choice, and FlareStarter's own dependency list shows how few pieces it takes: better-auth, Drizzle, Stripe, Resend, Tailwind, Radix. The starter's value is the wiring and the feature documentation, not the libraries.

Maintenance, licensing and the cost of a fork

The repository is not archived, and the last push was on 2026-08-07, which places it within the last two months. There are no releases retrieved, so there is no versioned upgrade path to follow: you fork main and track it yourself. That is normal for a starter and it changes the maintenance calculation. Upstream fixes do not arrive as a dependency bump; you either merge or you diverge.

FlareStarter is licensed under Apache-2.0, which permits commercial use and modification and includes a patent grant. It also requires that you preserve the licence and attribution notices for the parts you redistribute. The README mentions an "open-source core + lifetime Pro" model on the pricing page, so read the repository licence and the site's terms together before you assume the entire offering is covered by the Apache grant. This article is not legal advice; check the LICENSE file and the pricing page for your own case.

The practical upgrade cost is the migration folder. Drizzle migrations are ordered files, and a fork that edits them instead of adding new ones will fight every upstream schema change. Add migrations, do not rewrite them.

Editorial conclusion

Adopt FlareStarter if your product fits Cloudflare Workers, D1 and R2 and you want auth, billing and email already wired rather than assembled from five libraries. Skip it if you need Postgres, long-running background jobs, or a stack you can host outside Cloudflare, because the D1 binding and workerd runtime are load-bearing here. Before forking, verify three things yourself: that the drizzle/ migration folder covers the tables your feature needs, that the Stripe webhook path survives a replay in your own test environment, and that the plan gate you plan to reuse is the one the docs describe for your route type.

Frequently asked questions

What is FlareStarter built with?

It is a full-stack SaaS starter built on TanStack Start and Cloudflare Workers, using D1 for data, KV and R2 for supporting storage, Drizzle ORM for the schema, better-auth for authentication and Stripe for billing. The primary language is TypeScript and the licence is Apache-2.0.

How do I install and run FlareStarter locally?

Install dependencies with pnpm, apply the local D1 migrations, seed the database and start the dev server. The scripts are db:migrate:local, db:seed:local and dev, and the dev server runs on port 3000. Copy wrangler.example.jsonc and .dev.vars.example for your own configuration.

Can I use FlareStarter without Cloudflare?

The README does not describe a non-Cloudflare deployment path, and the architecture depends on Cloudflare bindings: D1 for sessions and application data, R2 for object storage, and the workerd runtime, which the README cites as the reason React Email is not used for templates. Moving off Cloudflare means replacing those pieces rather than changing a configuration value.

Official sources

  1. FlareStarter/flarestarter on GitHub
  2. Issues
  3. License: Apache-2.0
  4. Project website
  5. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/flarestarter-flarestarter.svg)](https://hysenlabs.com/projects/flarestarter-flarestarter)