# launch-mvp wires Next.js, Supabase, Stripe and Resend into one starter

> The launch-mvp-stripe-nextjs-supabase repository is a MIT licensed template that gives you authentication, payments, transactional email, a signup trigger that creates the user row, the preferences row and a 48 hour trial, and a set of MCP integrations for agent driven work. It is a starting point rather than a product, and its two environment files disagree with each other about whether you are using test keys.

**ShenSeanChen/launch-mvp-stripe-nextjs-supabase** — Welcome to Sean's Open Source MVP Boilerplate Template for Production-Ready NextJS+Stripe+Supabase App.

- Repository: https://github.com/ShenSeanChen/launch-mvp-stripe-nextjs-supabase
- Website: https://www.youtube.com/watch?v=ad1BxZufer8&list=PLE9hy4A7ZTmpGq7GHf5tgGFWh2277AeDR&index=9
- Stars: 1,106 · Forks: 244
- Language: TypeScript
- License: MIT
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/shenseanchen-launch-mvp-stripe-nextjs-supabase

## The four services and where each one runs

The template is a Next.js application with a specific division of labour, and the readme draws it as a diagram of where things run. On the Vercel side there is the Next.js app, its API routes under /api/*, the website UI and the email service. On the Supabase side there is the PostgreSQL database, the database triggers using pg_net, and the edge functions running on the Deno runtime.

The feature list names the same pieces in user language: authentication with Supabase, Stripe payment integration, automated email workflows with Resend covering welcome, billing and cancellation emails, dark mode, responsive design, Tailwind CSS styling, Framer Motion animations, TypeScript support, an error boundary implementation, SEO optimisation, and MCP integration for AI powered development.

The package metadata shows what the code actually depends on. Next is 15.5.9, React and React DOM are 19, Tailwind is 3.4.1 and TypeScript is 5. Supabase appears twice, with @supabase/ssr for the server side rendering aware client and @supabase/supabase-js for the rest. Stripe is the stripe package at 17.5.0 with @stripe/stripe-js for the browser, plus @stripe/mcp. Resend is 6.8.0, and @react-email/components builds the email templates. The rest is a conventional modern stack, framer-motion, lucide-react, react-icons, react-error-boundary, posthog-js, axios, @headlessui/react and @floating-ui/react, @vercel/analytics and lodash.

Getting the code is a clone and an install, and the readme offers three routes for the first one: the GitHub template button for a fresh repository with clean history, a clone with the template history removed, which it recommends for production, and a fork for contributors who want to receive updates.

```bash
git clone https://github.com/ShenSeanChen/launch-mvp-stripe-nextjs-supabase my-full-stack-app
cd my-full-stack-app
rm -rf .git              # Remove template's git history
git init                 # Start fresh with your own history
```

and then the dependencies, with npm or yarn, and the development server with npm run dev.

The audience is a developer with a paid product idea and no interest in assembling that particular set of services from scratch.

## A signup trigger creates three rows and a 48 hour trial

The most reusable piece of the template is the database trigger the readme asks you to create in Supabase, and it is worth reading in full because it encodes the trial lifecycle in the database rather than in application code.

The trigger function is handle_new_user, a SECURITY DEFINER plpgsql function on public.users, and the readme tells you to enable Row Level Security for all tables and to create policies for authenticated users and for service roles before you create it.

The function does three things on insert. It inserts into public.users with the id, the email, created_at and updated_at, and an is_deleted flag set to false. It inserts into public.user_preferences with the user id and has_completed_onboarding set to false. And it inserts into public.user_trials with the user id, a trial_start_time of now, and a trial_end_time of now plus an interval of 48 hours.

The trigger itself is on_auth_user_created, AFTER INSERT ON auth.users, FOR EACH ROW, executing the function.

Two design decisions are worth naming. First, the trial is a database row with timestamps rather than a flag in a user table, which means the trial window can be queried and enforced with ordinary SQL and can expire without a scheduled job. Second, the is_deleted column on the user row is a soft delete, and the preferences row exists as a separate table so that the onboarding state is a first class thing rather than a column bolted onto the user.

There is a separate initial_supabase_table_schema.sql at the root of the repository, which is presumably the schema this trigger expects, and the supabase directory holds the rest of the backend configuration.

## Stripe: a Buy Button, a payment link and four webhook event families

The Stripe setup in the readme is unusually specific, which makes it a good guide to what the template expects.

During development the instruction is to use TEST mode, with the test mode toggle in the top right of the Stripe dashboard, and the test card number 4242 4242 4242 4242. You create a product in the Product Catalog, create promotional coupon codes, and set up a Payment Link with a trial period.

The keys are then mapped to variables, and the mapping tells you which part of the app touches Stripe. The publishable key, a pk_test_xxx value, becomes NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY, so it is the browser side. The secret key, sk_test_xxx, becomes STRIPE_SECRET_KEY, so it is the server side. The Buy Button ID becomes NEXT_PUBLIC_STRIPE_BUTTON_ID, which means the checkout surface in this template is a Stripe payment link and a Buy Button rather than a hand built checkout form.

Webhooks are the part you must get right. The endpoint is your_url/api/stripe/webhook, and you subscribe to customer.subscription.*, checkout.session.*, invoice.* and payment_intent.*. The signing secret from that endpoint becomes STRIPE_WEBHOOK_SECRET.

The four event families are the contract between Stripe and the template, and they are also the contract between Stripe and the email automation, since the billing and cancellation emails are triggered by the events arriving there. A team that changes its subscription model will need to revisit that list.

## Email automation runs in Supabase, not in the Next app

The email section of the readme is where the template's structure pays off, and it also explains why two of the environment variables exist.

The template includes automated transactional emails using Supabase Database Triggers, Supabase Edge Functions and Resend. When a user signs up, subscribes or cancels, they automatically receive the corresponding email.

The architecture is the interesting part. The web app on Vercel runs the website UI, the API routes and the email service, while the database triggers and the edge functions live in Supabase. A trigger fires on a table change, and rather than the Next app needing to be awake and reachable, the Supabase side initiates the work, which means the welcome email does not depend on a request being in flight when the user signs up.

That design is also why the environment file carries INTERNAL_API_KEY alongside RESEND_API_KEY, with the comment that it is the internal API key for Edge Functions to call the email API, and that it can be the same as the Resend key or a separate secret.

The emails themselves live in the emails/ directory at the root of the repository, and the dependency on @react-email/components is the evidence for how they are written, as React components rather than HTML templates.

For a team that wants to change the sending logic, this is the file to look at, and for a team that wants to keep Resend but change the trigger, it is the Supabase side. The readme points at a video walkthrough for this section, which is a fair sign that it is the part with the most moving pieces.

## The two environment files disagree about test keys

There is a detail in this template that will cost somebody an afternoon, and it is worth writing about because both files look authoritative.

The .env.example in the readme shows development values. NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY is set to pk_test_, STRIPE_SECRET_KEY to sk_test_ and STRIPE_WEBHOOK_SECRET to whsec_, with a warning to use test keys during development.

The .env.example in the repository has the opposite default. NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY is pk_live_, STRIPE_SECRET_KEY is sk_live_ and STRIPE_WEBHOOK_SECRET is whsec_, with the test forms present but commented out. The only variable left in a test state is NEXT_PUBLIC_STRIPE_BUTTON_ID, which is buy_btn_.

So the file you are told to copy from, the .env.example at the root, is configured for live mode by default. The readme tells you to create .env.local with all variables from .env.example, and if you follow that literally with the Stripe keys you are pointed at live mode.

The rest of the file is consistent between the two, with NEXT_PUBLIC_APP_URL, NEXT_PUBLIC_API_URL and NEXT_PUBLIC_WS_URL pointing at localhost on ports 8000 and 8080, the Supabase URL, anon key and service role key, an OPENAI_API_KEY slot, the Resend key, the PostHog key and host, and the two paths. The .env.example in the repository adds a comment that the Supabase dashboard now calls these the publishable key and the secret key, but that the variable names still work correctly.

Two smaller inconsistencies sit alongside. The readme's step 8 tells you to open http://localhost:3000 in the browser, while the app URL in both environment files is http://localhost:8000. And the badges at the top of the readme say Next.js 14 and TypeScript 5.0, while the package metadata pins next at 15.5.9 and React at 19.

None of these are fatal, and all of them are the kind of thing a template can only fix by being maintained, which brings us to the last point.

## MCP integration, the agent angle, and the release history

The MCP integration is listed both as a feature and as a release, and it is the piece that tells you which way this template is aimed.

The dependency list includes @stripe/mcp and, in the dev dependencies, @supabase/mcp-server-supabase. The stripe one gives an agent the ability to work with Stripe, and the Supabase one the ability to work with the database, and the readme describes the feature as MCP integration for AI powered development. The repository has a .cursor/ directory, which is the client side of that idea, and the whole project is framed as an open source MVP boilerplate for a production ready Next.js, Stripe and Supabase app.

The release history is short. There is an MCP-Integration release on 2025-04-15 and v2.0.0 on 2026-01-21, titled Email Automation with Resend, so the two headline features of the current code arrived a year apart, in the order you would expect.

The repository is not archived and the last push was on 2026-07-20, roughly three months before this writing. That is a slow patch cadence for a template that people are expected to start a business on, and it is the main thing to weigh.

One more detail about the project name, because it is telling. The package name in the manifest is you-can-build-anything and the version is 0.1.0, and the package is marked private so it never goes to npm. That is an accurate description of what a template is, a starting point you are meant to rename, and it is also a reminder that the version number in the manifest is not a version of the product you are shipping, it is a version of the template.

The MIT licence and the CONTRIBUTING.md at the root are the only constraints on what you do with it.

## Conclusion

launch-mvp is worth adopting if you are starting a paid web product and want the plumbing for authentication, checkout, trial lifecycle and transactional email already written, because the database trigger and the email automation are the parts that normally take a week and that the template has already wired up. It is the wrong choice if you want a product rather than a starting point, because the package name is you-can-build-anything and the version is 0.1.0, and it is the wrong choice if you need an audited base. Before you build on it, read both .env.example files carefully, since the one in the repository holds live Stripe key placeholders while the one in the readme shows test keys, and note that the last push was on 2026-07-20 with the newest release v2.0.0 from 2026-01-21.

## FAQ

### What does the launch-mvp template include out of the box?

Authentication with Supabase, Stripe payment integration with a Buy Button and a payment link, automated email workflows with Resend covering welcome, billing and cancellation, dark mode, responsive design, Tailwind styling, Framer Motion animations, an error boundary, SEO optimisation and MCP integration for AI powered development.

### How does the launch-mvp template handle the signup trial?

With a database trigger. The readme asks you to create a SECURITY DEFINER function named handle_new_user and a trigger on_auth_user_created that runs after insert on auth.users. The function inserts a row into public.users, a row into public.user_preferences with has_completed_onboarding set to false, and a row into public.user_trials with a trial end time 48 hours after the start.

### Which Stripe keys and webhooks does launch-mvp expect?

The publishable key maps to NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY, the secret key to STRIPE_SECRET_KEY and the Buy Button ID to NEXT_PUBLIC_STRIPE_BUTTON_ID. The webhook endpoint is your_url/api/stripe/webhook, subscribed to customer.subscription.*, checkout.session.*, invoice.* and payment_intent.*, and its signing secret becomes STRIPE_WEBHOOK_SECRET.

### Where does the transactional email sending happen in launch-mvp?

On the Supabase side, not in the Next application. The architecture described in the readme puts the website UI, the API routes and the email service on Vercel, and the database triggers using pg_net plus the edge functions on the Deno runtime in Supabase, which is why the environment files include an INTERNAL_API_KEY for edge functions to call the email API.

### Are the launch-mvp environment templates safe to copy as they are?

Check them first. The .env.example in the repository defaults the Stripe variables to live mode placeholders, pk_live_ and sk_live_, with the test forms commented out, while the readme shows the test key values. The rest of the variables are the same in both files, and the readme's badges also lag behind the package metadata, which pins Next 15.5.9 and React 19.

## Sources

- [License: MIT](https://github.com/ShenSeanChen/launch-mvp-stripe-nextjs-supabase/blob/main/LICENSE)
- [Project website](https://www.youtube.com/watch?v=ad1BxZufer8&list=PLE9hy4A7ZTmpGq7GHf5tgGFWh2277AeDR&index=9)
- [README](https://github.com/ShenSeanChen/launch-mvp-stripe-nextjs-supabase/blob/main/README.md)
- [Releases](https://github.com/ShenSeanChen/launch-mvp-stripe-nextjs-supabase/releases)
- [ShenSeanChen/launch-mvp-stripe-nextjs-supabase on GitHub](https://github.com/ShenSeanChen/launch-mvp-stripe-nextjs-supabase)

---

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