Building an Authentication Starter: Lessons from Integrating Next.js, PostgreSQL, Prisma, and NextAuth
Source: Dev.to
Introduction
When starting a new web project, setting up user authentication can feel like a significant initial friction. Managing user data, securing routes, handling different login methods, and keeping everything type‑safe are common challenges. To address this, I created a Next.js authentication starter app that provides a solid foundation for future projects, handling these complexities out of the box.
Core Technologies
| Technology | Reason for Choice |
|---|---|
| Next.js 14 (App Router) | Clear route definition and data fetching, especially for server‑side rendered apps. |
| PostgreSQL | Stable, widely used relational database. |
| Prisma | Type‑safe ORM that simplifies database interactions and migrations. |
| NextAuth.js | Handles session management, social logins (Google, GitHub), and callbacks with minimal configuration. |
| Resend | Developer‑friendly API for sending verification and password‑reset emails. |
| Tailwind CSS & ShadCN | Rapid styling and a collection of accessible UI components. |
| Zod | Schema‑based form validation, ensuring data is correctly formatted and type‑safe. |
| bcryptjs | Secure password hashing. |
Features
- User Forms: Login, registration, email verification, password update, and password reset pages. Supports both email/password and social logins (Google, GitHub).
- Protected Routes:
middleware.tschecks user sessions before granting access to protected pages (e.g.,/settings). - Email Verification & Password Reset: Secure token generation and email delivery via Resend.
- Data Handling: Separation of concerns with
actions/for mutations anddata/for read‑only operations.
Project Layout
app/ # Route definitions (public and protected)
actions/ # Server actions for DB mutations
data/ # Read‑only data fetching functions
components/ # Reusable UI elements
lib/ # General utilities and helpers
prisma/ # Prisma schema and generated client
schemas/ # Zod validation schemas
middleware.ts # Route protection logic
auth.config.ts # NextAuth configuration (providers, callbacks)
Example: NextAuth Configuration (auth.config.ts)
import NextAuth from "next-auth";
import GoogleProvider from "next-auth/providers/google";
import GitHubProvider from "next-auth/providers/github";
export const authOptions = {
providers: [
GoogleProvider({ clientId: process.env.GOOGLE_ID!, clientSecret: process.env.GOOGLE_SECRET! }),
GitHubProvider({ clientId: process.env.GITHUB_ID!, clientSecret: process.env.GITHUB_SECRET! }),
],
callbacks: {
async session({ session, token }) {
session.user.id = token.sub;
return session;
},
},
};
export default NextAuth(authOptions);
Example: Zod Schema (schemas/login.ts)
import { z } from "zod";
export const loginSchema = z.object({
email: z.string().email(),
password: z.string().min(8),
});
Takeaways
- Explicit Validation with Zod: Catches errors early and provides clear feedback for form inputs.
- Separation of Concerns: Distinguishing between
actions/(mutations) anddata/(queries) simplifies server‑side logic and improves maintainability. - Flexibility in Data Fetching: The starter works with TanStack Query,
useSWR, or any other fetching strategy.
Alternatives Considered
- ORMs: Explored Neon, but Prisma’s TypeScript type‑safety and developer experience made it a better fit for a starter kit.
- Email Services: Many options exist; Resend was chosen for its straightforward API, but swapping to another provider is simple.
Conclusion
This Next.js authentication starter combines well‑regarded tools to address common authentication challenges. It offers a reliable starting point for applications that need user authentication with Next.js 14. Feel free to explore the repository, adapt components, or suggest improvements.
Next.js Auth Starter