Connect a Turso DB to Your Nuxt Project with Drizzle
Introduction
This guide is part of the DB series on the Foundry, focusing on Nuxt and compatible databases and ORMs. We'll walk through connecting a Turso database to your Nuxt project using Drizzle as the ORM.
Click here to start setting up a new Turso DB
You can also find the complete code on GitHub if you prefer.
Setup
Step 1: Create a new Nuxt project
Open a terminal and run:
pnpm dlx nuxi@latest init <your-project-name>
Step 2: Install dependencies
Install the necessary packages:
pnpm add drizzle-orm @libsql/client drizzle-kit
pnpm add -D @nuxtjs/tailwindcss
Step 3: Set up environment variables
Create a .env
file in your project root with the following content:
TURSO_DB_URL=
TURSO_DB_AUTH_TOKEN=
Backend Configuration
Step 4: Create server folders
Create the following folder structure in your project root:
server
utils
database
Step 5: Configure database connection
Create server/utils/db.ts
:
import { drizzle } from "drizzle-orm/libsql";
import { createClient } from "@libsql/client";
export const database = createClient({
url: process.env.DATABASE_URL!,
authToken: process.env.DATABASE_AUTH_TOKEN!,
});
export const orm = drizzle(database);
Step 6: Define database schema
Create server/database/schema.ts
:
import { InferModel } from 'drizzle-orm'
import { sqliteTable, text, integer, unique } from 'drizzle-orm/sqlite-core'
export const tickets = sqliteTable('messages', {
id: integer('id').primaryKey(),
name: text('name').notNull(),
email: text('email').notNull(),
body: text('body').notNull()
})
export type Ticket = InferModel<typeof tickets>;
export type InsertTicket = InferModel<typeof tickets, "insert">;
InferModel
from drizzle-orm is deprecated. Replace it with a more up-to-date method for production use.Steps 7-8: Set up API routes
Create the following folder structure:
server
api
tickets
Step 9: Implement GET endpoint
Create server/api/tickets/index.get.ts
:
import { tickets } from "../../database/schema";
import { orm } from "../../utils/db";
export default defineEventHandler(async () => {
try {
const allTickets = orm.select().from(tickets).all();
return { "tickets" : allTickets}
} catch (e: any) {
throw createError({
statusCode: 400,
statusMessage: e.message,
});
}
});
Step 10: Implement POST endpoint
Create server/api/tickets/createTicket.post.ts
:
import { tickets, InsertTicket } from "../../database/schema";
import { orm } from "../../utils/db";
export default defineEventHandler(async (event) => {
try {
const body = await readBody(event);
const newTicket: InsertTicket = {
...body
}
const result = orm.insert(tickets).values(newTicket).run();
return { newTicket : result}
} catch (e: any) {
throw createError({
statusCode: 400,
statusMessage: e.message,
});
}
});
Step 11 (Optional): Implement DELETE endpoint
Create server/api/tickets/deleteById/[...id].ts
:
import { tickets } from "../../../database/schema";
import { orm } from "../../../utils/db";
import { eq } from "drizzle-orm";
export default defineEventHandler(async (event) => {
try {
const ticketId = event.context.params?.id as string;
if(!ticketId) throw createError({
statusCode: 400,
statusMessage: "Ticket ID is required",
});
const allTickets = orm
.delete(tickets)
.where(eq(tickets.id, parseInt(ticketId)))
.run();
return { tickets: allTickets };
} catch (e: any) {
throw createError({
statusCode: 400,
statusMessage: e.message,
});
}
});
Database Deployment
Step 12: Configure Drizzle
Create drizzle.config.ts
in your project root:
import type { Config } from "drizzle-kit";
export default {
schema: "./server/utils/db/schema.ts",
driver: "turso",
dbCredentials: {
url: process.env.TURSO_DB_URL as string,
authToken: process.env.TURSO_DB_AUTH_TOKEN as string,
},
} satisfies Config;
Step 13: Push schema to Turso
Run the following command:
pnpm drizzle-kit push:sqlite --config=drizzle.config.ts
Frontend Implementation
Step 14: Update app.vue
Edit app.vue
:
<template>
<div>
<NuxtPage />
</div>
</template>
Step 15: Create index page
Create pages/index.vue
with a form to create new tickets.
Step 16: Create tickets page
Create pages/tickets.vue
to display all tickets.
Conclusion
You've now successfully connected a Turso database to your Nuxt project using Drizzle! This setup provides a solid foundation for building database-driven applications with Nuxt.
For the complete implementation and more details, check out the GitHub repository.
User Auth and Session Management in Nuxt with Sidebase and Strapi v4
Learn how to implement user authentication and session management in a Nuxt application using Sidebase Nuxt-Auth module and Strapi v4 as the backend.
Connect Nuxt and Nitro with Native WebSockets over H3 WebSockets and CrossWS
Discover the seamless integration of H3 CrossWS Websockets in Nitro and Nuxt projects for real-time communication capabilities.