Writing ·
Prisma ORM and Turso (with Next.js 14+ App Router) (English Version)
By combining Prisma and Turso, we can manage and deploy cloud-native SQLite-based Next.js applications.
Originally published in 2024. Examples reflect the versions used at the time. This migrated edition omits old dashboard screenshots and CLI help output, and replaces connection details with safe placeholders.
Prisma ORM offers the advantage of writing schemas simply, and its prisma-client can be used in the backend with type safety. Prisma supports various SQL-based DBMS, one of which is SQLite. When deploying an application, we also need a place to store our SQLite-based data. One DBaaS choice for SQLite is Turso.
In this article, I will share how to use Turso and Prisma with Next.js 14+ (App Router).
Preparing
Before using Turso, we need to set up Next.js and Prisma first.
Installing Next.js
To install Next.js, run the following, then navigate into the application folder:
npx create-next-app my-next-app
cd my-next-app
Installing Prisma
npm install @prisma/client
npm install prisma --save-dev
npx prisma init
Setup Prisma
Define the schema model in /prisma/schema.prisma:
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "sqlite"
url = "file:./dev.db"
}
model Post {
id Int @id @default(autoincrement())
title String
content String?
createdAt DateTime @default(now())
}
Run the migration:
npx prisma migrate dev --name init
The migration named init generates an SQL file at
/prisma/migrations/[date]_init/migration.sql and a Prisma Client that can be
used to access models with type safety. If the client is not generated, run:
npx prisma generate
Integrating Prisma with Next.js
Create /src/server/db.ts:
import { PrismaClient } from "@prisma/client"
const createPrismaClient = () =>
new PrismaClient({
log:
process.env.NODE_ENV === "development"
? ["query", "error", "warn"]
: ["error"],
})
const globalForPrisma = globalThis as unknown as {
prisma: ReturnType<typeof createPrismaClient> | undefined
}
export const db = globalForPrisma.prisma ?? createPrismaClient()
if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = db
This allows us to call the Prisma client using the db variable.
Turso
Installing Turso CLI
Turso provides a command-line interface for managing databases. The original Homebrew installation command was:
brew install tursodatabase/tap/turso
turso --help
Turso login
Visit Turso and sign in. I used the GitHub provider. Then return to the terminal:
turso auth login
Turso dashboard
In the dashboard, open Databases and choose Create Database. Enter a database
name and group. In this example, I named the database testing. After creation,
open that database's dashboard.
Connecting Prisma to Turso
Create a local .env file:
TURSO_DATABASE_URL=
TURSO_AUTH_TOKEN=
Get the database details with:
turso db show testing
Populate the environment file using your own database URL and token. These are placeholders, not working credentials:
TURSO_DATABASE_URL=libsql://your-database.turso.io
TURSO_AUTH_TOKEN=your-private-token
Never share your auth token or commit your local .env file.
Prisma adapter
In the Prisma version used for this article, add driverAdapters to the generator:
generator client {
provider = "prisma-client-js"
previewFeatures = ["driverAdapters"]
}
Update /src/server/db.ts to create a LibSQL client and adapter:
import { PrismaClient } from "@prisma/client"
import { PrismaLibSQL } from "@prisma/adapter-libsql"
import { createClient } from "@libsql/client"
const libsql = createClient({
url: `${process.env.TURSO_DATABASE_URL}`,
authToken: `${process.env.TURSO_AUTH_TOKEN}`,
})
const adapter = new PrismaLibSQL(libsql)
const createPrismaClient = () =>
new PrismaClient({
adapter,
log:
process.env.NODE_ENV === "development"
? ["query", "error", "warn"]
: ["error"],
})
const globalForPrisma = globalThis as unknown as {
prisma: ReturnType<typeof createPrismaClient> | undefined
}
export const db = globalForPrisma.prisma ?? createPrismaClient()
if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = db
Run the migration again:
npx prisma migrate dev --name init
Push migration to Turso
The original workflow pushed the generated SQL with the database shell. Replace the database name and migration path with your own:
turso db shell testing < ./prisma/migrations/20240902093411_init/migration.sql
Return to the dashboard and inspect the data with the available database editor.
The Post table should now be present. If the database is inactive, check its
status and settings in the dashboard.
Conclusion
By combining Prisma and Turso, we can manage and deploy cloud-native Next.js applications based on SQLite. Turso provides cloud-hosted SQLite, while Prisma helps manage database schemas with type safety in TypeScript.