Kickstarting Your SaaS App: The nextjs/saas-starter Explained
Think of nextjs/saas-starter as a pre-built foundation for a Software as a Service (SaaS) application. Instead of spending weeks setting up the essential components, this starter kit gives you a solid, production-ready stack right out of the box.
As a software engineer, this is incredibly valuable because it lets you
Focus on Your Core Product
You can bypass the tedious, repetitive work of configuring a database, setting up authentication, and integrating a payment system. This starter kit handles all that for you, allowing you to jump straight into building the unique features that make your application special.
Build with a Proven Stack
The project uses a set of robust and widely-adopted technologies
Next.js
A powerful React framework for building fast, full-stack web applications.
Postgres
A reliable and scalable relational database.
Stripe
The industry standard for online payments and subscriptions.
shadcn/ui
A collection of beautiful, reusable UI components built on top of Tailwind CSS.
See a Working Example
It's not just a collection of libraries; it's a complete, working example of a SaaS application. You can see how all the pieces fit together, from the database schema to the user interface, which is a fantastic learning resource.
Getting this project running is straightforward. You'll need a few prerequisites installed on your machine
Node.js, npm (or yarn / pnpm), and Git.
Here's the step-by-step process
Clone the Repository
First, get a local copy of the project.
git clone https://github.com/nextjs/saas-starter.git
Navigate into the Directory
Move into the newly created project folder.
cd saas-starter
Install Dependencies
Install all the necessary packages.
npm install
Set up Environment Variables
Copy the example environment file and fill it with your own keys. You'll need to create accounts with Stripe and Postgres (or use a local instance).
cp .env.example .env
Open the .env file and add your DATABASE_URL and Stripe keys.
Run the Database Migrations
This step sets up your database schema.
npx prisma migrate dev
Run the Development Server
Finally, start the application!
npm run dev
Your application will now be running locally, usually at http://localhost:3000.
Let's look at a couple of examples to show you how a software engineer would interact with this codebase.
The project uses Prisma for database access, which makes working with Postgres incredibly easy. You don't have to write raw SQL.
Here's an example of creating a new user after they sign up. The db object is your Prisma client.
// pages/api/auth/register.ts
import { db } from "@/lib/db";
import { hash } from "bcryptjs";
export default async function handler(req, res) {
const { email, password } = req.body;
// Hash the password for security
const hashedPassword = await hash(password, 10);
try {
const newUser = await db.user.create({
data: {
email,
password: hashedPassword,
},
});
res.status(201).json({ user: newUser });
} catch (error) {
console.error(error);
res.status(500).json({ error: "Something went wrong." });
}
}
Stripe integration is a core part of this kit. Here's a simplified look at how you might create a Stripe checkout session for a new subscription.
// pages/api/stripe/create-checkout-session.ts
import Stripe from "stripe";
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY, {
apiVersion: "2023-08-16",
});
export default async function handler(req, res) {
const { priceId } = req.body;
const userEmail = "[email protected]"; // Get this from your authenticated session
try {
const session = await stripe.checkout.sessions.create({
mode: "subscription",
line_items: [{ price: priceId, quantity: 1 }],
success_url: `${req.headers.origin}/dashboard?success=true`,
cancel_url: `${req.headers.origin}/pricing?canceled=true`,
customer_email: userEmail,
});
res.status(200).json({ sessionId: session.id });
} catch (error) {
console.error(error);
res.status(500).json({ error: "Something went wrong." });
}
}
The starter kit takes care of connecting the front-end to these API routes, so a user clicking "subscribe" will be redirected to the Stripe hosted checkout page seamlessly.