# mvp-boilerplate: a Flutter, NextJS and Supabase starter in one repository

> devtodollars/mvp-boilerplate is a monorepo that ships a Flutter app, a NextJS app and a Supabase backend with Stripe, PostHog and Loops.so already wired together. The value is the wiring; the cost is that several headline features are still marked as under construction and the setup path is a documentation site rather than a single command.

**devtodollars/mvp-boilerplate** — A mobile and/or web boilerplate that covers all your MVP needs

- Repository: https://github.com/devtodollars/mvp-boilerplate
- Website: https://devtodollars.com
- Stars: 996 · Forks: 123
- Language: TypeScript
- License: MIT
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/devtodollars-mvp-boilerplate

## Three applications share one repository root

The top level of the repository gives away the structure immediately: flutter/, nextjs/, supabase/, monero/, docs/ and a .github/ directory, with .env.example, CLAUDE.md, CODE_OF_CONDUCT.md, CONTRIBUTING.md and a LICENSE file at the root. The Flutter directory is labeled as covering mobile, desktop and web, and it takes riverpod for state management and go_router for routing. The NextJS directory is for a landing page or web app, built on the App Router with TypeScript. The Supabase directory holds the backend, and it is described as fully configured for local development from day one.

That arrangement is the actual product. Instead of choosing a starter for one layer and wiring it to a backend yourself, you get a client app, a web app and a database that already point at the same Supabase auth. The primary language of the repository is TypeScript and the default branch is main, so a Deno function in the Supabase folder and a Flutter screen are both just directories inside one checkout.

## The stripe table is where customer state actually lives

Payments are described as working for both one-time payments and subscriptions, and the interesting part is not the Stripe button but the bookkeeping behind it. There is a table named stripe that stores stripe_customer_id and the current active_products for each user, which means your application never has to treat the payment provider as the only source of truth. A Stripe webhook handles the return trip, syncing user subscriptions from Stripe back into Supabase.

The mobile side then calls a Deno function to retrieve either a billing portal URL or a checkout session URL, and that function is tied to the payments_screen in the Flutter app. So the checkout flow has three moving parts: a session created on the server, a screen in the app that opens it, and a webhook that writes the subscription back into the database. If you remove any one of them, the flow breaks in a way that is specific to this structure rather than generic.

## PostHog events are joined on user_id across client and server

Analytics run through PostHog with a stated goal of unified reporting across the frontend and the backend based on user_id. The frontend SDK is pre-installed for iOS, Android, Web and MacOS, and the backend side is installed and linked to the frontend analytics rather than kept as a separate stream.

A fixed set of events is captured out of the box: user signs in, user signs up, user deletes account, user starts checkout, user opens billing portal and user completes checkout. That list is short enough to read in one breath and it maps neatly onto the money and identity paths of the boilerplate, which is the point of capturing them at all. What is missing is equally notable. The README does not describe a way to add your own events, so a product with custom funnels would have to extend the tracking setup by hand, and it does not document the PostHog project setup or the API host configuration.

## Setup starts at a documentation site, then a .env file

There is no one line install command anywhere in the README, and there is no package name to run. The project instead points you at its own documentation to get started, and it publishes two live demos so you can see the finished result before touching any code: a Flutter demo and a NextJS demo. Work through the documentation for the setup steps that the README does not repeat.

The first concrete step you can see in the repository is the root.env.example, which lists every credential the code expects. Copy it to your own environment file and fill in the values for Google and GitHub OAuth, Stripe, PostHog, Loops.so and Supabase:

```yaml
GOOGLE_CLIENT_ID="YOUR_GOOGLE_CLIENT_ID"
GOOGLE_SECRET="YOUR_GOOGLE_SECRET"

GITHUB_CLIENT_ID="YOUR_GITHUB_CLIENT_ID"
GITHUB_SECRET="YOUR_GITHUB_SECRET"

STRIPE_SECRET_KEY="YOUR_STRIPE_SECRET_KEY"
STRIPE_WEBHOOK_SIGNING_SECRET="YOUR_STRIPE_WEBHOOK_SIGNING_SECRET"
POSTHOG_CLIENT_KEY="YOUR_POSTHOG_CLIENT_KEY"
LOOPS_API_KEY="YOUR_LOOPS_API_KEY"

SUPABASE_URL="YOUR_SUPABASE_URL"
SUPABASE_SERVICE_ROLE_KEY="YOUR_SUPABASE_SERVICE_ROLE_KEY"
```

That list doubles as a map of the integrations you sign up for on day one. Supabase, Stripe, PostHog and Loops.so each need a project, and the single sign-on options named in the backend section (Google, Github and similar providers) each need OAuth credentials registered in the same file. The service role key in particular is a backend secret, so treat the file as something that belongs on a server and never in a client bundle. Expect to spend the first afternoon on that documentation site.

## Six capabilities are still fenced off as under construction

Several of the most attractive features are marked in the README as not finished yet, and a buyer needs to see the whole list rather than the first two lines. Frontend tests for the Flutter side are open, as is the adjustable theme, which is tracked as an issue on the startup-boilerplate repository. The landing page template for NextJS is unfinished, backend tests are open on the Supabase side, automated mobile publishing is still on the roadmap, and Sentry error monitoring is listed with the same marker as the rest.

That is six gaps across testing, theming, release and observability, and they are not evenly distributed. Payments, auth, analytics and email are the finished parts, which happens to be a sensible shape for a product with revenue. The missing pieces are also the ones that tend to matter most after launch, when a flaky test suite or a missing error tracker starts costing hours. The README does not assign dates to any of these issues, so there is no way to judge from the documentation when they will land.

## bumpversion.sh and the Netlify preview carry the release path

Releases are handled through GitHub Actions rather than through tagged versions, and the repository publishes no GitHub releases at all. A script called bumpversion.sh follows semantic versioning, a web preview is deployed to Netlify for every pull request, and a publishing pipeline handles both the Netlify deployment and publishing the Supabase functions. Automated mobile publishing is the one item in this group that is not done.

Two consequences follow for anyone adopting this. First, because there are no published releases, you cannot pin a version of the boilerplate or diff against an earlier cut. The last push was on 2026-08-16, and any change you depend on lives in that commit rather than in a release artifact. Second, the pull request preview means visual review of the NextJS app does not require a local Node setup, which is the single most useful part of the pipeline for a small team. Mobile builds stay manual.

## What you inherit: a faster first week and a Dart codebase

The honest comparison is not against another product but against assembling the same stack yourself. Doing it from scratch means choosing a Flutter state library, a router, a Supabase auth flow, a Stripe webhook handler, an analytics SDK on two platforms and a transactional email service, then making them agree on a user identifier. This repository has already made those choices and documents the result.

The cost of those choices is visible in the tree. You get a Dart codebase and a TypeScript codebase in one repository, so a team strong in one language will be slower in the other. You also get an MIT licence, which allows commercial use and modification if you keep the copyright notice, and no vendor lock-in in the licence sense, though Supabase, Stripe, PostHog and Loops.so remain the assumed runtime. Email is handled by Loops.so with template based messages, variable support, contact management, event triggered campaigns and deliverability tracking, so swapping it later means rewriting that layer.

## Conclusion

Adopt mvp-boilerplate if your first release needs auth, subscriptions, analytics and transactional email inside one repository and you can live with a monorepo that mixes Dart and TypeScript. Skip it if you want one language end to end, or if the six features the README still marks as under construction are exactly the ones you need. Before you start, check the Flutter and NextJS demos, confirm the .env.example values you must supply, and read the .github/ workflows to see what actually deploys.

## FAQ

### What stack does devtodollars/mvp-boilerplate include?

It combines a Flutter app using riverpod and go_router, a NextJS app on the App Router with TypeScript, and a Supabase backend, plus Stripe payments, PostHog analytics, Loops.so email and GitHub Actions release tooling. The default branch is main and the licence is MIT.

### How do I install mvp-boilerplate?

The README contains no install command, so it directs you to the documentation at resources.devtodollars.com/docs to get started. You can also review the running demos at flutter.devtodollars.com and nextjs.devtodollars.com before copying the template.

### Which mvp-boilerplate features are not finished yet?

Frontend tests, the adjustable theme, the NextJS landing page template, backend tests, automated mobile publishing and Sentry error monitoring are all marked as under construction in the README. Auth, payments, analytics, email and the Netlify preview pipeline are the parts that are in place.

### How does mvp-boilerplate handle Stripe subscriptions?

A stripe table stores stripe_customer_id and the current active_products, a Stripe webhook syncs user subscriptions from Stripe into Supabase, and a Deno function returns a billing portal URL or a checkout session URL for the payments_screen in the Flutter app.

## Sources

- [devtodollars/mvp-boilerplate on GitHub](https://github.com/devtodollars/mvp-boilerplate)
- [Issues](https://github.com/devtodollars/mvp-boilerplate/issues)
- [License: MIT](https://github.com/devtodollars/mvp-boilerplate/blob/main/LICENSE)
- [Project website](https://devtodollars.com)
- [README](https://github.com/devtodollars/mvp-boilerplate/blob/main/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/devtodollars-mvp-boilerplate
