Skip to content
  • Integrations
  • Third-party tools

Set up a Next.js app with Drizzle ORM and Kinde

Discover how to integrate Kinde authentication seamlessly into a Next.js application while managing user data with a Drizzle-powered SQLite database.

This tutorial will guide you step-by-step through setting up your environment, installing the necessary dependencies, creating authentication routes, and using Drizzle Studio to inspect your database.

By the end of this guide, you’ll have a robust authentication flow complete with user management, fully prepared to support your application’s future development. Let’s go!

Step 1: Integrate Drizzle ORM with your Next.js project

Link to this section
  1. Change in to your Next.js project directory by entering the following command in your project terminal:

    cd my-nextjs-project
  2. Install Drizzle dependencies by entering the following command:

    Terminal window
    npm i drizzle-orm better-sqlite3
    Terminal window
    npm i -D drizzle-kit @types/better-sqlite3
  3. Create a configuration file for Drizzle in the root directory:

    Terminal window
    touch drizzle.config.ts
  4. Open the file with your preferred code editor, enter the following configuration options in the file and save:

    import { defineConfig } from "drizzle-kit"
    export default defineConfig({
    out: "./drizzle",
    schema: "./src/db/schema.ts",
    dialect: "sqlite",
    dbCredentials: {
    url: "./sqlite.db",
    },
    })
  5. Create a database schema file:

    Terminal window
    mkdir src/db
    touch src/db/schema.ts
  6. Enter the following code in schema.ts to construct your userTable schema and save the file.

    The code imports sqlite dependencies and creates a table called users_table in Drizzle with the following columns, id, kinde_id, first_name, last_name, and email.

    import { sqliteTable, text, integer } from "drizzle-orm/sqlite-core"
    export const usersTable = sqliteTable("users_table", {
    id: integer().primaryKey({ autoIncrement: true }),
    kindeId: text("kinde_id").notNull().unique(),
    firstName: text("first_name"),
    lastName: text("last_name"),
    email: text("email"),
    })
  7. Create an index.ts file in the db directory:

    Terminal window
    touch src/db/index.ts
  8. Enter the following code into the newly created index.ts file and save the changes.

    This creates a SQLite database instance and connects to Drizzle.

    import { drizzle } from "drizzle-orm/better-sqlite3"
    import Database from "better-sqlite3"
    const sqlite = new Database("sqlite.db")
    export const db = drizzle({ client: sqlite })
  9. Open the tsconfig.json file. Change the “target” from es5 to es6. Save the file.

    This is because Drizzle does not yet support es5.

    {
    "compilerOptions": {
    "target": "es6",
    ...
  10. Push the database changes by entering the following in your terminal:

    Terminal window
    npx drizzle-kit push

Step 2: Save user data to the database after authentication

Link to this section
  1. Create a new directory success and a route.ts file inside it with the following commands:

    This file will act as a GET route to interface with the database and handle user authentication data.

    Terminal window
    mkdir src/app/api/auth/success
    touch src/app/api/auth/success/route.ts
  2. Open the route.ts file in your code editor, add the following code, and then save the file.

    import { db } from "@/db"
    import { usersTable } from "@/db/schema"
    import { eq } from "drizzle-orm"
    import { getKindeServerSession } from "@kinde-oss/kinde-auth-nextjs/server"
    import { NextResponse } from "next/server"
    export async function GET() {
    const { getUser } = getKindeServerSession()
    const user = await getUser()
    if (!user || user == null || !user.id)
    throw new Error("something went wrong with authentication" + user)
    const dbUser = await db
    .selectDistinct()
    .from(usersTable)
    .where(eq(usersTable.kindeId, user.id))
    if (!dbUser.length) {
    await db.insert(usersTable).values({
    kindeId: user.id,
    firstName: user.given_name ?? "",
    lastName: user.family_name ?? "",
    email: user.email ?? "", // Using nullish coalescing operator to provide a default empty string value
    })
    }
    return NextResponse.redirect("/")
    }

    Here’s what the code does:

    • Imports the Drizzle database instance, and the user table function.
    • Imports functions to interact with the Kinde Server Session and handle the Next.js response.
    • Defines a GET route to retrieve the authenticated user’s information.
    • Checks if the user is already stored in the database and inserts user information if not.
  3. Open the .env or .env.local file in your project and update the KINDE_POST_LOGIN_REDIRECT_URL field with the following value:

    KINDE_POST_LOGIN_REDIRECT_URL=http://localhost:3000/api/auth/success

    This ensures that after a successful login, the user is redirected to this route, which updates the database and then redirects the user.

Step 3: Test the Drizzle integration

Link to this section
  1. Start your development server by running the following command in your terminal:

    Terminal window
    npm run dev
  2. Open your web browser and navigate to http://localhost:3000 to view your Kinde application locally.

  3. Select Sign Up to create a new user account. Enter the required details and complete the sign-up process.

  4. Open a new terminal window and start the Drizzle Studio with the following command:

    Terminal window
    npx drizzle-kit studio
  5. Go to https://local.drizzle.studio in your web browser to access Drizzle Studio and view your database.

  6. Select the users_table model to see the newly registered user details.

    drizzle studio

    You have now stored the user details in your local database using Drizzle.

You’ve successfully integrated Kinde authentication with your Next.js application and managed user data using a Drizzle-powered SQLite database. Your app now has a secure and scalable foundation.

Build on this by adding features like role-based access, custom user profiles, or API integrations. By leveraging Kinde and Drizzle, you’ve set the stage for a reliable and efficient authentication system. Keep innovating and enhancing!