Uses the official @bachs/sdk for hosted checkout, product setup, customer portal and webhook verification
bachs-nextjs-saas — Next.js SaaS Template
By bachsdev
A local development subscription template built on Next.js App Router and the Bachs SDK, demonstrating hosted checkout, webhook verification, access control and a customer billing portal.
Explore the design
Compare the page layouts and mobile experience. Open any screenshot for a closer look.
Actual browser screenshot from the verified demo.
All pages & views 2
Screenshots show visual appearance; interactive behavior may differ.
What stands out
A quick read of the recorded project description.
The checkout API maps plans server-side and saves persistent operation keys, ignoring client-side price and product IDs
The webhook route uses the SDK to verify the raw request body and event envelope, and lib/webhooks.ts skips duplicate and older events
lib/store.ts commits state together with processed event IDs to a local file using serialized, atomic replacement
Provides npm run verify to run unit/route tests, TypeScript checks, production build and HTTP smoke tests
Includes AGENTS.md, CLAUDE.md and a standalone Bachs skill file for AI-assisted development
Template Details
This is a Next.js App Router starter template for demonstrating Bachs monthly and annual subscription flows, using the official @bachs/sdk for checkout, product setup, customer portal and webhook verification. The README explicitly states that it is a local development starter template: all visitors share one demo user, billing data is stored in a local JSON file, and authentication and storage must be replaced before deployment; the demo authentication rejects live API keys. The template includes modules such as the checkout API, webhook handling, access control, customer portal session creation and a success page, and provides verification scripts for unit tests, type checking, production build and HTTP smoke tests. The README also records that a manual sandbox check passed on October 9, 2026, but subsequent billing cycle renewals have not been verified.
Is it right for your project?
Use Cases
- Experience the complete Bachs subscription checkout, webhook-activated access and customer billing portal flow in a local sandbox
- Use as a reference project for learning how to integrate Next.js App Router with the Bachs SDK
- Use as a starting point for building your own SaaS subscription features by replacing authentication, storage and plan configuration
- Use the built-in tests and verification scripts to check signature, renewal recovery, cancellation and concurrent event handling in the subscription lifecycle
Suitable For
- Developers who need to understand how Bachs subscription integration works
- Teams that want to build Next.js SaaS subscription features starting from a local development template
- People who need a reference implementation for webhook verification, access control and idempotent checkout handling
Getting started & customization
Use these recorded setup notes alongside the repository instructions for your chosen version.
- 1
Requires Node.js 22 or later, a sandbox API key and the Bachs CLI; the key needs products:write, payments:write and customers:write permissions
- 2
After running npm ci, copy .env.example to .env, set BACHS_API_KEY, then run npm run setup:products and put the two printed product IDs into .env
- 3
In a second terminal run npm run listen, copy the printed whsec_ key to BACHS_WEBHOOK_SECRET, then run npm run dev
- 4
Bachs rejects localhost and private IP checkout redirect URLs, so local development does not set a redirect by default; if automatic return is needed, use a public deployment or tunnel and set CHECKOUT_SUCCESS_URL and CHECKOUT_CANCEL_URL
- 5
Each new listen session generates a new signing key, so update .env and restart the app; do not paste keys into chat or commit .env
License & source material
Usage conditions & limitations
Free to use · keep license noticeThis entry covers the free version under the MIT license in the public repository; the free scope is the code of this version and does not mean external services or third-party assets are free.
Must comply with when using
- Free use, modification, commercial use and distribution of this version's code are allowed.
- When distributing copies or substantial portions of the code, retain the original author's copyright notice and the complete MIT license notice.
- The code is provided as is; warranties and limitations of liability are governed by the original license and applicable law.
Additional costs & items to verify
- Demo images, fonts, icons and other third-party assets must be checked against their respective licenses and cannot be judged solely by the code's MIT license.
- External services such as domains, hosting, databases, payments or AI may incur additional charges.
- This is a local development starter template: all visitors share one demo user, and billing data is stored in a local JSON file.
- Authentication and storage implementations must be replaced before deployment.
- The demo authentication rejects live API keys, so it cannot be used directly in production.
- The current 0.0.1 package on npm is only a placeholder; the SDK implementation is packaged in vendor/.
- Requires Node.js 22 or later, a sandbox API key and the Bachs CLI.
- The API key needs products:write, payments:write and customers:write permissions.
- Bachs rejects localhost and private IP checkout redirect URLs even in the sandbox.
- Each new listen session generates a new signing key; after restarting the listener, update .env and restart the app.
- Do not paste keys into chat, and do not commit the .env file.
- When investigating a lost checkout response, stop the app before editing the local .data/store.json file.
- The smoke tests use dummy keys and fixed API responses and do not perform real Bachs payments.
- Subsequent billing cycle renewals have not been verified; lifecycle tests use fixed events and cannot prove a real second charge.
- The local serialization in lib/store.ts only works for a single Node.js process and cannot coordinate multiple instances or serverless storage.
- The starter template's tests only target the shared demo identity; you must add your own session, authorization and deployment tests.
- Going live requires creating production products, setting BACHS_ENVIRONMENT=production, using production API URLs and live keys.
View Original Text Basis
Permission is hereby granted, free of charge
Original License Text
**This is a local development starter.** Every visitor shares one demo user,
Original README
and billing data lives in one local JSON file. Replace authentication and the
Original README
store before deploying. Demo authentication refuses live API keys.
Original README
vendor/ so npm ci works before its npm release. The current npm 0.0.1
Original README
You need Node.js 22 or later, a [sandbox API key](https://docs.bachs.io/authentication),
Original README
The key needs `products:write`, `payments:write`, and `customers:write`.
Original README
Bachs refuses localhost and private-IP checkout redirect URLs, even in sandbox.
Original README
Each new `listen` session has a new signing secret. Update `.env` and restart
Original README
the app when you restart the listener. Do not paste keys into chats or commit
Original README
`checkouts` in `.data/store.json`. Stop the app before editing that local file.
Original README
The smoke test uses dummy keys and fixture API responses. It makes no real
Original README
A subsequent billing-cycle renewal remains unverified. Lifecycle tests above
Original README
- Replace `lib/store.ts` with a transactional database. Its local serialization
Original README
- Add your app's session, authorization and deployment tests. This starter's
Original README
https://github.com/bachsdev/bachs-nextjs-saas/blob/main/LICENSEhttps://github.com/bachsdev/bachs-nextjs-saas/blob/main/README.mdCreate products in production, set BACHS_ENVIRONMENT=production, use the production API URL and live key, and
Original README
Compiled by DeepSeek based on repository license and README ·2026-10-09. Results only cover the materials read; dependencies, images, fonts, and subsequent term changes are subject to their respective original texts.
Project checks & description sources
Template Information
- Source platforms
- GitHub
- Documentation and maintenance reference score
- More documented · 85 / 100
- Technologies
- Next.js · React
- Website type
- SaaS · Starter
How this score is calculated
Our heuristic uses license records (up to 30), a demo link (12), a preview (10), stars (15), recorded maintenance (15), description completeness (8), feature records (5) and classification data (5). It is not a code, security or performance test, or a Google score. A link does not establish tested functionality.
What to verify for this project
- Repository update recorded
- 2026-10-09
- Screenshot last checked
- 2026-10-16
A demo link is listed. Check it with your own content and viewport sizes; its presence does not confirm that forms, authentication or payments work.
The catalog identifies Next.js as the primary stack. Check the actual dependency manifest and lockfile for versions and hosting requirements. These notes use recorded metadata, not a code audit or a deployment test.
Use a selection guide →How this description was prepared
AI-assisted description based on catalog records and repository material. Repository authors are not automatically the reviewers of this description.
Review declaration: codex-user-requested-batch-review-20261017 · 2026-10-16
Inspect the recorded source material
SHA-256: c8c48b0d73b53905c513962052f1efc5fb5ce6f3fac7a5cc142a839e69815208
2026-10-09T19:52:15.773Z
Source file / repository# Bachs Next.js SaaS starter A Next.js App Router starter for monthly and yearly [Bachs](https://bachs.io) subscriptions using the official [Bachs SDK](https://github.com/bachsdev/bachs-node): hosted checkout, access from verified webhooks, and customer billing through the Bachs customer portal. Follow the [SaaS subscriptions walkthrough](https://docs.bachs.io/build/use-cases/saas-subscriptions) for the payment flow and the [Build with AI subscription workflow](https://docs.bachs.io/build/ai#sell-subscriptions) for a prompt that adapts it to your app. **This is a local development starter.** Every visitor shares one demo user, and billing data lives in one local JSON file. Replace authentication and the store before deploying. Demo authentication refuses live API keys. ## SDK dependency This starter imports @bachs/sdk for checkout, product setup, the customer portal and webhook verification. The tested SDK implementation is packaged in vendor/ so npm ci works before its npm release. The current npm 0.0.1 package is a placeholder. See [package provenance and the npm transition](vendor/README.md). ## Run in sandbox You need Node.js 22 or later, a [sandbox API key](https://docs.bachs.io/authentication), and the [Bachs CLI](https://docs.bachs.io/cli/overview#install). The key needs `products:write`, `payments:write`, and `customers:write`. ```bash npm ci cp .env.example .env # Set BACHS_API_KEY in .env, then: npm run setup:products ``` On Windows PowerShell, use `Copy-Item .env.example .env` instead of `cp`. Copy the two product IDs printed by the setup script into `.env`. You can also create the recurring products in the Bachs dashboard and save their IDs there. In a second terminal: ```bash npm run listen ``` Copy the `whsec_` secret it prints into `BACHS_WEBHOOK_SECRET` in `.env`, then start the app: ```bash npm run dev ``` Open http://localhost:3000, click **Subscribe**, and complete the sandbox checkout using its test controls. Subscription webhooks activate access. Return to http://localhost:3000 after paying to see access activate. Click **Manage billing** to open the portal. Bachs refuses localhost and private-IP checkout redirect URLs, even in sandbox. The starter leaves checkout redirects unset for local development. If you want an automatic return, use a public deployment or tunnel and set `CHECKOUT_SUCCESS_URL` and `CHECKOUT_CANCEL_URL` in `.env`. `APP_URL` remains the app's own URL; the CLI forwards webhooks without a public webhook URL. Each new `listen` session has a new signing secret. Update `.env` and restart the app when you restart the listener. Do not paste keys into chats or commit `.env`. ## How it works | File | Responsibility | | --- | --- | | `app/api/checkout/route.ts` | Maps the plan on the server, reserves a persistent operation key, and creates checkout. Client prices and product IDs are ignored. | | `app/api/webhooks/bachs/route.ts` | Uses SDK webhooks.constructEvent to verify the raw body and event envelope, then processes the event. | | `lib/webhooks.ts` | Saves subscription state; skips duplicates and older events. | | `lib/store.ts` | Commits state and processed-event IDs together in a serialized, atomic local file replacement. | | `lib/access.ts` | Decides access. The default gives a grace period while a renewal is past due. | | `app/api/billing/portal/route.ts` | Creates a fresh session for the demo user's saved Bachs customer. | | `app/billing/success/page.tsx` | Reads stored access and waits for the webhook; never grants access. | | `lib/bachs.ts` | Maps app inputs to the official SDK; the SDK handles transport, typed responses and uncertain errors. | ### When a checkout response is lost The starter saves a checkout attempt before calling Bachs. A repeated click reuses a confirmed, unexpired checkout. A timeout, 5xx, or failure to save the response leaves the attempt awaiting confirmation and blocks another POST. Check the checkout or subscription in Bachs and allow its webhook to arrive. Keep the stored operation key while investigating. Only after confirming the original checkout had no effect should you clear that user's entry in `checkouts` in `.data/store.json`. Stop the app before editing that local file. In a production implementation, replace this manual step with an authenticated reconciliation process following the [idempotency guide](https://docs.bachs.io/guides/idempotency). Do not delete the store or generate a replacement key just because a response was lost. ## Verification ```bash npm run verify ``` This runs: 1. Unit and route tests for signatures, secret rotation, checkout and portal ownership, access, renewal recovery, cancellation, duplicate and concurrent events, failed persistence, and uncertain checkout recovery. 2. TypeScript checks. 3. A production build. 4. HTTP smoke checks against the built Next.js server and a local Bachs API fixture, with isolated billing data. The smoke test uses dummy keys and fixture API responses. It makes no real Bachs payment. Run the sandbox checkout above to verify a real integration. CI runs the same gates on Node.js 22 and 24 without secrets. A manual SDK-backed sandbox check on October 9, 2026 also passed: hosted checkout and the first payment, a real signed subscription event forwarded through the CLI after replay, stored access activation, and the signed-in demo customer's billing portal. The user submitted the simulated card payment. A subsequent billing-cycle renewal remains unverified. Lifecycle tests above use fixture events; they are not evidence of a real second charge. To run an individual gate: ```bash npm test npm run typecheck npm run build npm run test:smoke # requires npm run build first ``` ## Make it yours - Replace `lib/auth.ts` with authenticated users and protect billing routes. - Replace `lib/store.ts` with a transactional database. Its local serialization applies to one Node.js process; it cannot coordinate multiple instances or serverless storage. Preserve atomic event completion and stale-event checks. - Set your plans in `lib/plans.ts` and create matching Bachs products. Prices displayed in the app should match those products. - Choose the access policy in `lib/access.ts`. - Configure the [customer portal](https://docs.bachs.io/guides/customer-portal/overview#configuring-the-portal) for card updates and plan switching if needed. - Add your app's session, authorization and deployment tests. This starter's tests exercise a shared demo identity. ## Go live After replacing the demo components, follow the [go-live checklist](https://docs.bachs.io/build/use-cases/saas-subscriptions#go-live-checklist). Create products in production, set BACHS_ENVIRONMENT=production, use the production API URL and live key, and register the five subscription/invoice events in `npm run listen` on your production webhook endpoint. Its signing secret differs from the local one. Production subscriptions are not shared with sandbox. ## Building with an AI assistant `AGENTS.md` explains the project and checks; `CLAUDE.md` points to it. [Build with AI](https://docs.bachs.io/build/ai) has three complete workflows and an optional Bachs skill. The shared [Bachs skill](skills/bachs/SKILL.md) covers payments, subscriptions and marketplaces. You can use it in any app, independently of this starter. For Claude Code, copy skills/bachs/SKILL.md into your app at .claude/skills/bachs/SKILL.md, then use /bachs followed by what you want to build. For another tool that supports Agent Skills, install the same file using its instructions. Prefer no installation? Copy one of the three prompts from Build with AI; each includes the rules it needs. ## License MIT. See [LICENSE](LICENSE).
Explore similar templates
Compare previews and descriptions within the same stack and category.

Next.js SaaS Starter
The official Next.js SaaS starter template, integrating email/password authentication, Stripe Checkout subscriptions, a dashboard with user/team CRUD, basic Owner/Member RBAC, and activity logging.
Next.js · SaaS

Next.js Commerce
Vercel's officially maintained Next.js App Router ecommerce starter with deep Shopify integration, offering a complete product catalog, cart, and checkout flow. Core logic is modular for swapping backends, and community provider versions exist for BigCommerce, Medusa, and Saleor.
Next.js · E-commerce

Next-js-Boilerplate
A developer-first Next.js 16 starter with Tailwind CSS 4 and TypeScript, supporting both App Router and Page Router.
Next.js · Starter

tailwind-nextjs-starter-blog
A Next.js and Tailwind CSS blog starter template using Contentlayer for Markdown/MDX, with built-in SEO, code highlighting, and tags. It targets personal technical blogs and migration from Jekyll/Hugo to React, and supports one-click Vercel deployment.
Next.js · Blog

next-forge
next-forge is a Turborepo-based Next.js template maintained by Vercel, positioned as a starting point for SaaS products.
Next.js · Starter

SaaS-Boilerplate
SaaS-Boilerplate is an open-source SaaS starter template built with Next.js App Router, React 19, TypeScript, Tailwind CSS, and Shadcn UI.
Next.js · SaaS
