<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Oyekola Abdulqobid Bolaji</title>
    <description>The latest articles on DEV Community by Oyekola Abdulqobid Bolaji (@oyetech3).</description>
    <link>https://dev.to/oyetech3</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3576261%2F65544dea-2d1e-4cf6-bc64-3f11ef090566.jpg</url>
      <title>DEV Community: Oyekola Abdulqobid Bolaji</title>
      <link>https://dev.to/oyetech3</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/oyetech3"/>
    <language>en</language>
    <item>
      <title>Full-Stack Development Roadmap from Zero to Hero</title>
      <dc:creator>Oyekola Abdulqobid Bolaji</dc:creator>
      <pubDate>Wed, 29 Oct 2025 13:49:24 +0000</pubDate>
      <link>https://dev.to/oyetech3/full-stack-development-roadmap-from-zero-to-hero-35b9</link>
      <guid>https://dev.to/oyetech3/full-stack-development-roadmap-from-zero-to-hero-35b9</guid>
      <description>&lt;h2&gt;
  
  
  🔐 How to Set Up Authentication in Next.js 15 with Server Actions
&lt;/h2&gt;

&lt;p&gt;Authentication is one of the most important parts of any modern web application.&lt;br&gt;&lt;br&gt;
Whether you’re building a &lt;strong&gt;portfolio&lt;/strong&gt;, &lt;strong&gt;SaaS platform&lt;/strong&gt;, or &lt;strong&gt;e-commerce app&lt;/strong&gt;, you’ll need a way for users to securely &lt;strong&gt;sign up, log in, and manage their sessions&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In this guide, we’ll set up authentication in &lt;strong&gt;Next.js 15 (App Router)&lt;/strong&gt; using &lt;strong&gt;modern best practices&lt;/strong&gt; — no external auth libraries required.  &lt;/p&gt;

&lt;p&gt;We’ll use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; &lt;strong&gt;TypeScript&lt;/strong&gt; for type safety
&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Server Actions&lt;/strong&gt; for form handling
&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Cookies/Sessions&lt;/strong&gt; for authentication state
&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Tailwind CSS&lt;/strong&gt; for styling
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By the end, you’ll have a fully functional authentication system with:&lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;User Registration&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Login &amp;amp; Logout&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Protected Routes&lt;/strong&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  ❓ Why Authentication Matters
&lt;/h2&gt;

&lt;p&gt;Before we dive into code, let’s understand &lt;strong&gt;why authentication is essential&lt;/strong&gt; for every modern app:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; &lt;strong&gt;Keeps user data secure&lt;/strong&gt; — protects sensitive information from unauthorized access.
&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Enables personalized experiences&lt;/strong&gt; — dashboards, user settings, and custom content.
&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Builds trust&lt;/strong&gt; — users feel safe knowing their data is handled responsibly.
&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Foundation for advanced features&lt;/strong&gt; — payments, subscriptions, and role-based access all depend on a solid auth system.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  1️⃣ Step 1: Setting Up the Next.js Project
&lt;/h2&gt;

&lt;p&gt;Let’s start by creating a new &lt;strong&gt;Next.js 15&lt;/strong&gt; project configured with &lt;strong&gt;TypeScript&lt;/strong&gt; and &lt;strong&gt;Tailwind CSS&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx create-next-app@latest my-auth-app &lt;span class="nt"&gt;--typescript&lt;/span&gt; &lt;span class="nt"&gt;--tailwind&lt;/span&gt;
&lt;span class="nb"&gt;cd &lt;/span&gt;my-auth-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copy the commands above into your terminal — this will give you a fresh &lt;strong&gt;Next.js 15&lt;/strong&gt; setup with the &lt;strong&gt;App Router&lt;/strong&gt; enabled.&lt;/p&gt;




&lt;h2&gt;
  
  
  2️⃣ Step 2: Creating the Database Model
&lt;/h2&gt;

&lt;p&gt;For simplicity, we’ll use &lt;strong&gt;Prisma&lt;/strong&gt; with &lt;strong&gt;SQLite&lt;/strong&gt; (you can easily switch to PostgreSQL or MySQL later).&lt;/p&gt;

&lt;h3&gt;
  
  
  Install Prisma
&lt;/h3&gt;

&lt;p&gt;Run the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;prisma @prisma/client
npx prisma init &lt;span class="nt"&gt;--datasource-provider&lt;/span&gt; sqlite
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Update Your Prisma Schema
&lt;/h3&gt;

&lt;p&gt;Open your &lt;strong&gt;&lt;code&gt;prisma/schema.prisma&lt;/code&gt;&lt;/strong&gt; file and update it with the following model definition:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;model User {
  id        Int      @id @default(autoincrement())
  email     String   @unique
  password  String
  createdAt DateTime @default(now())
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then migrate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx prisma migrate dev &lt;span class="nt"&gt;--name&lt;/span&gt; init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Don't worry if you want to know more about Prisma, I will cover that in another blog soon&lt;/p&gt;




&lt;h2&gt;
  
  
  3️⃣ Step 3: Creating the Registration Page
&lt;/h2&gt;

&lt;p&gt;We’ll use Next.js Server Actions for form submissions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;app/register/page.tsx&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;use client&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;RegisterPage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setLoading&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleRegister&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;FormEvent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nf"&gt;setLoading&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;formData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FormData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;currentTarget&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/api/register&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="nf"&gt;setLoading&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt; &lt;span class="na"&gt;onSubmit&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleRegister&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"max-w-sm mx-auto mt-10"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;
        &lt;span class="na"&gt;placeholder&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Email"&lt;/span&gt;
        &lt;span class="na"&gt;required&lt;/span&gt;
        &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"w-full mb-3 px-3 py-2 border rounded"&lt;/span&gt;
      &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt;
        &lt;span class="na"&gt;placeholder&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Password"&lt;/span&gt;
        &lt;span class="na"&gt;required&lt;/span&gt;
        &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"w-full mb-3 px-3 py-2 border rounded"&lt;/span&gt;
      &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;
        &lt;span class="na"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"w-full bg-blue-600 text-white py-2 rounded hover:bg-blue-700"&lt;/span&gt;
      &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;loading&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Registering...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Register&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  4️⃣ Step 4: Creating the API Route for Registration
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;app/api/register/route.ts&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;NextResponse&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;next/server&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;bcrypt&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bcrypt&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;prisma&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@/lib/prisma&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;formData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;email&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;password&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hashedPassword&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;bcrypt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;prisma&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;hashedPassword&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;NextResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  5️⃣ Step 5: Login &amp;amp; Session Handling
&lt;/h2&gt;

&lt;p&gt;We’ll use cookies to keep users logged in.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;**app/api/login/route.ts&lt;/code&gt;**&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;NextResponse&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;next/server&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;bcrypt&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bcrypt&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;prisma&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@/lib/prisma&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;cookies&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;next/headers&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;formData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;email&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;password&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;prisma&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findUnique&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;where&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;NextResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Invalid credentials&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;401&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;valid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;bcrypt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;valid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;NextResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Invalid credentials&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;401&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="c1"&gt;// Await the cookies() call&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cookiesStore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;cookies&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;cookiesStore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;httpOnly&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;secure&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NODE_ENV&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;production&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;sameSite&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lax&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;NextResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  6️⃣ Step 6: Protecting Routes
&lt;/h2&gt;

&lt;p&gt;We can read cookies inside server components:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;cookies&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;next/headers&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Link&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;next/link&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;DashboardPage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cookiesStore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;cookies&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;cookiesStore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;

        &lt;span class="nx"&gt;You&lt;/span&gt; &lt;span class="nx"&gt;must&lt;/span&gt; &lt;span class="nx"&gt;log&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;view&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
        &lt;span class="nx"&gt;Go&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;Login&lt;/span&gt;

    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;

      &lt;span class="nx"&gt;Welcome&lt;/span&gt; &lt;span class="nx"&gt;back&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  7️⃣ Step 7: Logout
&lt;/h2&gt;

&lt;p&gt;We can read cookies inside server components:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// app/api/logout/route.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;NextResponse&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;next/server&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;cookies&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;next/headers&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cookiesStore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;cookies&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nx"&gt;cookiesStore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;NextResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🏁 Wrapping Up
&lt;/h2&gt;

&lt;p&gt;And that’s it 🎉 — you’ve just built a simple authentication system in &lt;strong&gt;Next.js 15&lt;/strong&gt; using the &lt;strong&gt;App Router&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Through this project, you’ve learned:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;⚡ How powerful &lt;strong&gt;Server Actions&lt;/strong&gt; and &lt;strong&gt;API Routes&lt;/strong&gt; are in Next.js 15
&lt;/li&gt;
&lt;li&gt;🧠 How &lt;strong&gt;TypeScript&lt;/strong&gt; makes authentication logic safer and easier to maintain
&lt;/li&gt;
&lt;li&gt;🎨 How &lt;strong&gt;Tailwind CSS&lt;/strong&gt; helps you build clean, responsive forms quickly
&lt;/li&gt;
&lt;li&gt;☁️ How seamless &lt;strong&gt;Vercel deployments&lt;/strong&gt; are with modern Next.js setups
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;This setup is perfect for &lt;strong&gt;learning and small-scale projects&lt;/strong&gt;.  &lt;/p&gt;

&lt;p&gt;💡 For production-grade apps, consider using &lt;strong&gt;&lt;a href="https://next-auth.js.org/" rel="noopener noreferrer"&gt;NextAuth.js&lt;/a&gt;&lt;/strong&gt; (now &lt;strong&gt;Auth.js&lt;/strong&gt;) — it provides ready-made solutions for:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;OAuth (Google, GitHub, etc.)
&lt;/li&gt;
&lt;li&gt;JWTs and sessions
&lt;/li&gt;
&lt;li&gt;Advanced security features
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With this foundation in place, you’re well on your way to building &lt;strong&gt;secure, scalable full-stack applications&lt;/strong&gt; with Next.js 15.&lt;/p&gt;




&lt;h2&gt;
  
  
  Read the Full Article
&lt;/h2&gt;

&lt;p&gt;This is a summary of my comprehensive guide. Read the full article with code examples and project ideas on my blog:&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://oyetech.vercel.app/blog/how-to-set-up-authentication-in-nextjs" rel="noopener noreferrer"&gt;How to Set Up Authentication in Next.js 15 with Server Actions&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;More tutorials on my blog:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://oyetech.vercel.app/blog/nextjs-16-whats-new" rel="noopener noreferrer"&gt;Next.js 16: What’s New and Why It’s a Game-Changer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://oyetech.vercel.app/blog/fullstack-development-roadmap" rel="noopener noreferrer"&gt;Full-Stack Development Roadmap - Complete Guide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Connect with me:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🌐 Website: &lt;a href="https://oyetech.vercel.app" rel="noopener noreferrer"&gt;oyetech.vercel.app&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;💼 LinkedIn: [&lt;a href="http://linkedin.com/in/oyekola-abdulqobid-bolaji-999490271" rel="noopener noreferrer"&gt;http://linkedin.com/in/oyekola-abdulqobid-bolaji-999490271&lt;/a&gt;]&lt;/li&gt;
&lt;li&gt;🐦 Twitter: [@OyekolaAbdulqo1]&lt;/li&gt;
&lt;li&gt;💻 GitHub: [&lt;a href="https://github.com/Oyetech3" rel="noopener noreferrer"&gt;https://github.com/Oyetech3&lt;/a&gt;]&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Questions?
&lt;/h2&gt;

&lt;p&gt;What's your biggest challenge in learning full-stack development? Drop a comment below!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; #webdev #nextjs #authentication  #tutorial&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>nextjs</category>
      <category>authentication</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Next.js 16: What’s New and Why It’s a Game-Changer</title>
      <dc:creator>Oyekola Abdulqobid Bolaji</dc:creator>
      <pubDate>Sun, 26 Oct 2025 15:03:27 +0000</pubDate>
      <link>https://dev.to/oyetech3/nextjs-16-whats-new-and-why-its-a-game-changer-1nc8</link>
      <guid>https://dev.to/oyetech3/nextjs-16-whats-new-and-why-its-a-game-changer-1nc8</guid>
      <description>&lt;h2&gt;
  
  
  🚀 Next.js 16: What’s New and Why It’s a Game-Changer
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Next.js has long been the go-to framework for building modern React applications. With each release, it has introduced features that push the web forward—whether it’s hybrid rendering, file-based routing, or the powerful App Router.&lt;/p&gt;

&lt;p&gt;But with &lt;strong&gt;Next.js 16&lt;/strong&gt;, Vercel has delivered one of the most significant updates yet. This release introduces &lt;strong&gt;performance breakthroughs&lt;/strong&gt;, &lt;strong&gt;refined caching&lt;/strong&gt;, &lt;strong&gt;smarter routing&lt;/strong&gt;, and &lt;strong&gt;developer experience upgrades&lt;/strong&gt; that make building scalable web apps faster and easier.&lt;/p&gt;

&lt;p&gt;In this article, we’ll break down:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The key new features in Next.js 16
&lt;/li&gt;
&lt;li&gt;How it differs from previous versions (especially Next.js 15)
&lt;/li&gt;
&lt;li&gt;Migration considerations for existing projects
&lt;/li&gt;
&lt;li&gt;Example snippets to help you get started&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Key Features in Next.js 16
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1️⃣ Turbopack as Default Bundler
&lt;/h3&gt;

&lt;p&gt;Next.js 16 makes &lt;strong&gt;Turbopack&lt;/strong&gt; the default bundler, replacing Webpack in new projects.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; Up to &lt;strong&gt;10x faster&lt;/strong&gt; local refreshes
&lt;/li&gt;
&lt;li&gt; Smarter incremental builds
&lt;/li&gt;
&lt;li&gt; Designed to handle large codebases without slowing down&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx create-next-app@latest my-app
&lt;span class="c"&gt;# Turbopack runs by default in dev mode&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you still need Webpack, you can opt-in manually — but most developers will want the speed of Turbopack.&lt;/p&gt;




&lt;h2&gt;
  
  
  2️⃣ Improved Caching &amp;amp; Data Fetching APIs
&lt;/h2&gt;

&lt;p&gt;The caching layer has been &lt;strong&gt;reworked for finer-grained control&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;New APIs like &lt;code&gt;updateTag()&lt;/code&gt; complement &lt;code&gt;revalidateTag()&lt;/code&gt; for smarter cache invalidation.&lt;br&gt;&lt;br&gt;
Better defaults for &lt;strong&gt;incremental revalidation&lt;/strong&gt; and mixing &lt;strong&gt;static + dynamic data&lt;/strong&gt; make real-time-ish experiences much simpler to implement.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// app/api/posts/route.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;revalidateTag&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;updateTag&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;next/cache&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;createPost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

  &lt;span class="c1"&gt;// Invalidate old cache&lt;/span&gt;
  &lt;span class="nf"&gt;revalidateTag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;posts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="c1"&gt;// Mark as updated for downstream fetches&lt;/span&gt;
  &lt;span class="nf"&gt;updateTag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;posts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives you &lt;strong&gt;precise control&lt;/strong&gt; over how data is refreshed — super useful for dashboards, feeds, or fast-changing content.&lt;/p&gt;




&lt;h2&gt;
  
  
  3️⃣ Smarter Routing &amp;amp; Navigation
&lt;/h2&gt;

&lt;p&gt;Next.js 16 introduces &lt;strong&gt;layout deduplication&lt;/strong&gt; and &lt;strong&gt;incremental prefetching&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Layouts reuse shared UI across routes more efficiently.
&lt;/li&gt;
&lt;li&gt;Prefetching downloads only what’s necessary, reducing wasted requests.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;💨 &lt;strong&gt;Result:&lt;/strong&gt; navigation feels even snappier for end users.&lt;/p&gt;




&lt;h2&gt;
  
  
  4️⃣ React 19 Support (Experimental)
&lt;/h2&gt;

&lt;p&gt;Next.js 16 brings compatibility with &lt;strong&gt;React 19&lt;/strong&gt; features, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; &lt;strong&gt;View Transitions API&lt;/strong&gt; (smooth client-side page transitions)
&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Improved async server components&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;More stable hooks&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🧪 &lt;strong&gt;Note:&lt;/strong&gt; React 19 support may still be experimental — test the features that matter most to your app before fully adopting them.&lt;/p&gt;




&lt;h2&gt;
  
  
  5️⃣ Build Adapters API
&lt;/h2&gt;

&lt;p&gt;A new &lt;strong&gt;Adapters API&lt;/strong&gt; lets you deploy Next.js apps beyond Vercel:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; Cloudflare Workers
&lt;/li&gt;
&lt;li&gt; Deno
&lt;/li&gt;
&lt;li&gt; Bun
&lt;/li&gt;
&lt;li&gt; Custom infrastructure
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This provides &lt;strong&gt;more flexibility&lt;/strong&gt; for teams that need multi-platform deployment options and aren’t tied to a single hosting provider.&lt;/p&gt;




&lt;h2&gt;
  
  
  6️⃣ Breaking Changes &amp;amp; Removals
&lt;/h2&gt;

&lt;p&gt;Next.js 16 includes a few important breaking changes to be aware of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; &lt;strong&gt;AMP support removed&lt;/strong&gt; (AMP is deprecated in most modern workflows)
&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Middleware file naming:&lt;/strong&gt; &lt;code&gt;middleware.ts&lt;/code&gt; is now the recommended convention
&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Minimum versions:&lt;/strong&gt; Node.js &lt;strong&gt;18+&lt;/strong&gt; and TypeScript &lt;strong&gt;5+&lt;/strong&gt; are required
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Plan upgrades accordingly&lt;/strong&gt; — review the official migration guide if you rely on any deprecated APIs or older tooling.&lt;/p&gt;




&lt;h2&gt;
  
  
  How Next.js 16 Differs from Previous Versions
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Feature&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Next.js 15&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Next.js 16&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Bundler&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Webpack (default)&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Turbopack&lt;/strong&gt; (default)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Data Caching&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Basic &lt;code&gt;revalidateTag()&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Fine-grained cache APIs (&lt;code&gt;updateTag&lt;/code&gt;, &lt;code&gt;revalidateTag&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Routing Prefetch&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Prefetch whole pages&lt;/td&gt;
&lt;td&gt;Incremental prefetch (faster, smaller)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;React Support&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;React 18&lt;/td&gt;
&lt;td&gt;React 19 (experimental)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Deployment Targets&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Vercel-first&lt;/td&gt;
&lt;td&gt;Build Adapters for multi-platform&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AMP&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Supported&lt;/td&gt;
&lt;td&gt;Removed&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;👉 &lt;strong&gt;In short:&lt;/strong&gt; Next.js 16 is &lt;strong&gt;faster&lt;/strong&gt;, &lt;strong&gt;leaner&lt;/strong&gt;, and &lt;strong&gt;more flexible&lt;/strong&gt; than ever — thanks to Turbopack, improved caching, smarter prefetching, and multi-platform build adapters.&lt;/p&gt;




&lt;h2&gt;
  
  
  Migration Considerations
&lt;/h2&gt;

&lt;p&gt;If you’re upgrading from &lt;strong&gt;Next.js 15 → 16&lt;/strong&gt;, here’s what to keep in mind before rolling it out to production:&lt;/p&gt;




&lt;h3&gt;
  
  
  1️⃣ Check Your Node.js Version
&lt;/h3&gt;

&lt;p&gt;Make sure your environment meets the minimum requirements:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node &lt;span class="nt"&gt;-v&lt;/span&gt;
&lt;span class="c"&gt;# Must be &amp;gt;= 18&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2️⃣ Upgrade TypeScript
&lt;/h3&gt;

&lt;p&gt;Make sure you’re on TypeScript 5+.&lt;/p&gt;

&lt;h3&gt;
  
  
  3️⃣ Rename Middleware Files (if needed)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;middleware.js → middleware.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4️⃣ Remove or Refactor AMP
&lt;/h3&gt;

&lt;p&gt;Search your codebase for AMP dependencies and update pages.&lt;/p&gt;

&lt;h3&gt;
  
  
  5️⃣ Test Turbopack in Dev
&lt;/h3&gt;

&lt;p&gt;Large codebases may hit edge cases — run your dev environment and verify parity:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run dev
&lt;span class="c"&gt;# or&lt;/span&gt;
pnpm dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6️⃣ Verify Third-Party Plugins &amp;amp; Tooling
&lt;/h3&gt;

&lt;p&gt;Some plugins/loaders built for Webpack might need replacements or polyfills.&lt;/p&gt;




&lt;h2&gt;
  
  
  Example: Migrating Cache Logic
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Before (Next.js 15):
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;revalidateTag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;posts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Now (Next.js 16):
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;revalidateTag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;posts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;updateTag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;posts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// ensures downstream fetches know about update&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use the two APIs together for both invalidation and propagation signals.&lt;/p&gt;




&lt;h2&gt;
  
  
  ✅ When to Adopt Next.js 16
&lt;/h2&gt;

&lt;p&gt;Thinking about upgrading? Here’s what’s recommended based on your project type:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Project Type&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Recommendation&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;🟢 &lt;strong&gt;Greenfield Projects&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Start directly with &lt;strong&gt;Next.js 16&lt;/strong&gt; — benefit from Turbopack, React 19, and new caching APIs.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🟡 &lt;strong&gt;Medium Projects&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Upgrade to gain performance boosts and better cache precision.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🔵 &lt;strong&gt;Large / Enterprise Apps&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Test &lt;strong&gt;Turbopack&lt;/strong&gt; thoroughly before switching production builds.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;🚀 &lt;strong&gt;If performance, caching control, or React 19 features matter to your app&lt;/strong&gt;, adopting Next.js 16 is absolutely worth exploring.&lt;/p&gt;




&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Next.js 16 isn’t just an incremental update — it’s a &lt;strong&gt;major leap forward&lt;/strong&gt;.  &lt;/p&gt;

&lt;p&gt;By making &lt;strong&gt;Turbopack&lt;/strong&gt; the default, refining &lt;strong&gt;caching APIs&lt;/strong&gt;, improving &lt;strong&gt;routing and prefetching&lt;/strong&gt;, and adding &lt;strong&gt;React 19 support&lt;/strong&gt;, it sets a &lt;strong&gt;new standard for fast, scalable, and future-proof web applications&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;💡 Whether you’re building your first Next.js project or maintaining a large-scale platform, &lt;strong&gt;Next.js 16 brings the speed, flexibility, and developer experience to take your apps to the next level.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Read the Full Article
&lt;/h2&gt;

&lt;p&gt;This is a summary of my comprehensive guide. Read the full article with code examples and project ideas on my blog:&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://oyetech.vercel.app/blog/nextjs-16-whats-new" rel="noopener noreferrer"&gt;Next.js 16: What’s New and Why It’s a Game-Changer&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;More tutorials on my blog:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://oyetech.vercel.app/blog/how-to-set-up-authentication-in-nextjs" rel="noopener noreferrer"&gt;How to Set Up Authentication in Next.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://oyetech.vercel.app/blog/fullstack-development-roadmap" rel="noopener noreferrer"&gt;Fullstack-Development-Roadmap&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Connect with me:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🌐 Website: &lt;a href="https://oyetech.vercel.app" rel="noopener noreferrer"&gt;oyetech.vercel.app&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;💼 LinkedIn: [&lt;a href="http://linkedin.com/in/oyekola-abdulqobid-bolaji-999490271" rel="noopener noreferrer"&gt;http://linkedin.com/in/oyekola-abdulqobid-bolaji-999490271&lt;/a&gt;]&lt;/li&gt;
&lt;li&gt;🐦 Twitter: [@OyekolaAbdulqo1]&lt;/li&gt;
&lt;li&gt;💻 GitHub: [&lt;a href="https://github.com/Oyetech3" rel="noopener noreferrer"&gt;https://github.com/Oyetech3&lt;/a&gt;]&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Questions?
&lt;/h2&gt;

&lt;p&gt;What's your biggest challenge in learning Nextjs ? Drop a comment below!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; #webdev #nextjs #frontend #tutorial&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Full-Stack Development Roadmap from Zero to Hero</title>
      <dc:creator>Oyekola Abdulqobid Bolaji</dc:creator>
      <pubDate>Tue, 21 Oct 2025 07:36:18 +0000</pubDate>
      <link>https://dev.to/oyetech3/full-stack-development-roadmap-from-zero-to-hero-466b</link>
      <guid>https://dev.to/oyetech3/full-stack-development-roadmap-from-zero-to-hero-466b</guid>
      <description>&lt;h2&gt;
  
  
  🚀 Full-Stack Development Roadmap: From Zero to Hero
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;A complete guide from absolute beginner to job-ready engineer&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Becoming a &lt;strong&gt;full-stack developer&lt;/strong&gt; means you can build entire web applications — from the polished interface a user sees to the server logic and database that power it.  &lt;/p&gt;

&lt;p&gt;This guide breaks the journey into clear phases so you know &lt;strong&gt;what to learn&lt;/strong&gt;, &lt;strong&gt;why it matters&lt;/strong&gt;, and &lt;strong&gt;in what order&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  1️⃣ Why Full-Stack
&lt;/h2&gt;

&lt;p&gt;Full-stack developers build entire web applications — the user interface &lt;strong&gt;and&lt;/strong&gt; the behind-the-scenes APIs, servers, and databases.&lt;/p&gt;

&lt;h3&gt;
  
  
  Companies love full-stack engineers because they can:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Ship features end-to-end.
&lt;/li&gt;
&lt;li&gt;Understand how front-end and back-end choices affect each other.
&lt;/li&gt;
&lt;li&gt;Work on small teams without heavy specialization.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your goal is to launch your own &lt;strong&gt;SaaS&lt;/strong&gt;, work in a &lt;strong&gt;startup&lt;/strong&gt;, or just stay &lt;strong&gt;versatile&lt;/strong&gt;, full-stack is a smart path.&lt;/p&gt;




&lt;h2&gt;
  
  
  2️⃣ Core Foundations (Month 1–2)
&lt;/h2&gt;

&lt;p&gt;Before touching any framework, master the raw building blocks.&lt;/p&gt;

&lt;h3&gt;
  
  
  HTML
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Semantic tags (&lt;code&gt;&amp;lt;header&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;article&amp;gt;&lt;/code&gt;)
&lt;/li&gt;
&lt;li&gt;Forms, accessibility (ARIA roles), SEO-friendly structure
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  CSS
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Box model, positioning, flexbox, CSS grid
&lt;/li&gt;
&lt;li&gt;Responsive design with media queries
&lt;/li&gt;
&lt;li&gt;Transitions &amp;amp; animations
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  JavaScript (ES6+)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Variables (&lt;code&gt;let&lt;/code&gt;, &lt;code&gt;const&lt;/code&gt;), arrow functions
&lt;/li&gt;
&lt;li&gt;Async programming: &lt;code&gt;promises&lt;/code&gt;, &lt;code&gt;async/await&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;DOM manipulation, events, &lt;code&gt;fetch&lt;/code&gt; API
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Git &amp;amp; GitHub
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Cloning, branching, pull requests, resolving merge conflicts
&lt;/li&gt;
&lt;li&gt;Writing clear commit messages
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;💡 &lt;strong&gt;Goal:&lt;/strong&gt; Build and deploy a small static site with interactive JS (e.g., a to-do list) using &lt;strong&gt;GitHub Pages&lt;/strong&gt; or &lt;strong&gt;Netlify&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  3️⃣ Front-End Specialization (Month 3–5)
&lt;/h2&gt;

&lt;p&gt;Modern applications demand structure and performance.&lt;/p&gt;

&lt;h3&gt;
  
  
  Core Libraries &amp;amp; Frameworks
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;React&lt;/strong&gt; – Hooks, Context API, React Router
&lt;/li&gt;
&lt;li&gt;Alternatives: Vue 3 or Svelte, but React dominates 2025 job boards
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  TypeScript
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Interfaces, generics, and strong typing
&lt;/li&gt;
&lt;li&gt;Prevents runtime bugs and improves autocomplete
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Styling Approaches
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tailwind CSS&lt;/strong&gt; utility-first workflow
&lt;/li&gt;
&lt;li&gt;Component libraries: &lt;code&gt;shadcn/ui&lt;/code&gt;, Chakra UI, Radix
&lt;/li&gt;
&lt;li&gt;CSS Modules or Styled Components (if not using Tailwind)
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  State &amp;amp; Data
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Global state: Redux Toolkit or Zustand
&lt;/li&gt;
&lt;li&gt;Server state: React Query (TanStack Query)
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Front-End Tooling
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Vite or &lt;strong&gt;Next.js 15&lt;/strong&gt; for fast builds &amp;amp; SSR/SSG
&lt;/li&gt;
&lt;li&gt;ESLint + Prettier for code quality
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;💡 &lt;strong&gt;Goal:&lt;/strong&gt; Build a responsive SPA that consumes a public API (e.g., weather dashboard, movie search, etc.).&lt;/p&gt;




&lt;h2&gt;
  
  
  Back-End Fundamentals (Month 6–8)
&lt;/h2&gt;

&lt;p&gt;Learn to create APIs and manage data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Node.js &amp;amp; Express/Fastify
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Routing, middleware, error handling&lt;/li&gt;
&lt;li&gt;RESTful design principles
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Example project setup&lt;/span&gt;
&lt;span class="nb"&gt;mkdir &lt;/span&gt;my-api &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;my-api
npm init &lt;span class="nt"&gt;-y&lt;/span&gt;
npm &lt;span class="nb"&gt;install &lt;/span&gt;express
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Databases
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Relational (SQL): PostgreSQL or MySQL.&lt;/li&gt;
&lt;li&gt;NoSQL: MongoDB for flexible schemas.&lt;/li&gt;
&lt;li&gt;ORMs: Prisma or TypeORM.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Authentication &amp;amp; Security
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Sessions vs. JWT tokens.&lt;/li&gt;
&lt;li&gt;OAuth (Google, GitHub).&lt;/li&gt;
&lt;li&gt;Hashing passwords with bcrypt/argon2.&lt;/li&gt;
&lt;li&gt;Preventing XSS/CSRF and SQL injection.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Testing
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Jest or Vitest for unit tests.&lt;/li&gt;
&lt;li&gt;Supertest for API endpoint testing.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;💡&lt;strong&gt;Goal:&lt;/strong&gt; Create a REST API with authentication and a CRUD resource (e.g., a notes app) and connect it to your React front-end.&lt;/p&gt;




&lt;h2&gt;
  
  
  5️⃣ Going Full-Stack (Month 9–11)
&lt;/h2&gt;

&lt;p&gt;Combine the front and back into a single, production-ready application.&lt;/p&gt;

&lt;h3&gt;
  
  
  Frameworks for Both Ends
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Next.js 15 – file-based routing, server actions, API routes, SSR/SSG.&lt;/li&gt;
&lt;li&gt;Lets you write front-end and back-end code in one project.&lt;/li&gt;
&lt;li&gt;tRPC or GraphQL (Apollo/Urql) for type-safe APIs.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Real-World Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;File uploads (AWS S3/Cloudinary).&lt;/li&gt;
&lt;li&gt;Payments (Stripe).&lt;/li&gt;
&lt;li&gt;Real-time updates with WebSockets or Socket.IO.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Performance
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Caching strategies.&lt;/li&gt;
&lt;li&gt;Image optimization, lazy loading, Core Web Vitals.
💡&lt;strong&gt;Capstone Project Idea:&lt;/strong&gt; A small SaaS product—e.g., a project management tool with user auth, team collaboration, and billing.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  6️⃣ DevOps &amp;amp; Deployment (Month 12)
&lt;/h2&gt;

&lt;p&gt;You built it—now ship it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hosting:&lt;/strong&gt; Vercel or Netlify for JAMstack; Render, Railway, or AWS for custom Node servers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CI/CD:&lt;/strong&gt; GitHub Actions or GitLab CI for automated tests and deploys.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitoring&lt;/strong&gt;: Sentry for error tracking, Logtail or Datadog for logs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Containers:&lt;/strong&gt; Docker basics for reproducible builds.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  7️⃣ Suggested Year-Long Timeline
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Quarter&lt;/th&gt;
&lt;th&gt;Focus&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Q1&lt;/td&gt;
&lt;td&gt;HTML, CSS, JS, Git&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Q2&lt;/td&gt;
&lt;td&gt;React + TypeScript + Tailwind&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Q3&lt;/td&gt;
&lt;td&gt;Node.js, Express, PostgreSQL/MongoDB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Q4&lt;/td&gt;
&lt;td&gt;Next.js full-stack project, deployment, CI/CD&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  🎯 Final Thoughts
&lt;/h2&gt;

&lt;p&gt;The stack evolves, but the fundamentals &lt;strong&gt;-HTML, CSS, JavaScript, HTTP, and problem-solving—&lt;/strong&gt; are timeless. Treat this roadmap as a flexible guide: build real projects at every stage, share your work on GitHub, and write about what you learn.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; Don’t wait until you “know everything” to apply for jobs. Employers value projects and proof you can learn quickly more than a checklist of buzzwords.&lt;/p&gt;




&lt;h2&gt;
  
  
  Read More on My Blog
&lt;/h2&gt;

&lt;p&gt;This article was originally published on my blog: &lt;br&gt;
&lt;a href="https://oyetech.vercel.app/blog/fullstack-development-roadmap" rel="noopener noreferrer"&gt;Full-Stack Development Roadmap&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For more tutorials on web development, visit &lt;a href="https://oyetech.vercel.app" rel="noopener noreferrer"&gt;OyeTech&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Follow me:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Twitter: &lt;a href="https://x.com/oyekolaabdulqo1?s=21" rel="noopener noreferrer"&gt;@oyekolaabdulqo1&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/Oyetech3" rel="noopener noreferrer"&gt;Oyetech3&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;LinkedIn: &lt;a href="http://linkedin.com/in/oyekola-abdulqobid-bolaji-999490271" rel="noopener noreferrer"&gt;Oyekola Abdulqobid Bolaji&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Questions?
&lt;/h2&gt;

&lt;p&gt;Drop a comment below! I'd love to hear about your full-stack journey.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>tutorial</category>
      <category>fullstack</category>
    </item>
  </channel>
</rss>
