Building an Authentication Starter: Lessons from Integrating Next.js, PostgreSQL, Prisma, and NextAuth

Published: (May 9, 2026 at 07:36 AM EDT)
3 min read
Source: Dev.to

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

TechnologyReason for Choice
Next.js 14 (App Router)Clear route definition and data fetching, especially for server‑side rendered apps.
PostgreSQLStable, widely used relational database.
PrismaType‑safe ORM that simplifies database interactions and migrations.
NextAuth.jsHandles session management, social logins (Google, GitHub), and callbacks with minimal configuration.
ResendDeveloper‑friendly API for sending verification and password‑reset emails.
Tailwind CSS & ShadCNRapid styling and a collection of accessible UI components.
ZodSchema‑based form validation, ensuring data is correctly formatted and type‑safe.
bcryptjsSecure 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.ts checks 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 and data/ 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) and data/ (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

0 views
Back to Blog

Related posts

Read more »