Drizzle ORM with Sveltekit

Mohammed Anas
5 min readNov 19, 2023

--

Drizzle is an really awesome tool if you wanna work with SQL databases , I’ve been using it for my recent projects , and it’s has a really great DX which i’ve fallen in love with.

This Blog is for ppl who are getting started with Sveltekit and Drizzle , Which is really powerful when we combine them with TS.

Setup

There are multiple ways of getting this setup done , I’m gonna share my preference which i’ve found really useful when i’ve been using Drizzle.

pnpm create svelte@latest

This will scaffold a basic sveltekit project. I highly recommend you to use Typescript , as Drizzle and Sveltekit has first class TS support.

pnpm add drizzle-orm # install Drizzle
pnpm add -D drizzle-kit#This has all the goodies that drizzle provides

Once this is done the next step is to setup a database , which in your case can be any SQL flavoured db , i’m gonna use Postgres for this example.

pnpm add postgres

Environmet Setup

Lets create a .env file with the db credentials.

#.env
DATABASE_URL = postgres://example:example@localhost:5432/test

After this if you run you dev server with npm run dev svletekit will generate the types for you Environmental variables .

Drizzle ORM Setup

Create all you db Related files in the src/lib/db folder.

Setting up your connection in db/db.server.ts , Here we use .server.ts extenstion to let sveltekit know that we are using a server only modules and this can’t be used in any client side code.

// db/db.server.ts
import { drizzle } from 'drizzle-orm/postgres-js';
import postgres from 'postgres';
import { DATABASE_URL } from '$env/static/private';
import { dev } from '$app/environment';

// const client = dev ? postgres(DATABASE_URL) : postgres(DATABASE_URL, { ssl: 'require' });
const client = postgres(DATABASE_URL)
export const db = drizzle(client, {});

We are adding some additional features for production build , so that we can support ssl support when running on production , you can opt in if you want to.

Some ppl might run their migrations from here , but i prefer to run my migrations manually so that i know what exact changes are reflected in my database

You can either have a single schema file or a directory (visit example 3).

// src/lib/db/schema.ts

import { pgTable,serial,text } from "drizzle-orm/pg-core";

export const myTable = pgTable("myTableName",{
id:serial("id").primaryKey(),
name:text("name").notNull(),
})

Drizzle has good support for schema types. And one awesome feature is whenever you find something missing with drizzle , they make sure they give you a generic way to build it yourself in a very simple manner like custom types.

These are the little things that made me comeback to Drizzle over a long period of time.

This is all you need to get started with drizzle orm for you applications. But I extend this setup with some goodies provided by Drizzle Orm to move faster and have a better DX.

Setting Up migrations and Schema Generation

If we wanna run migrations from our app , we can conveniently do it by creating a drizzle.config.ts file in the root of your directory.

// drizzle.config.ts
import type { Config } from 'drizzle-kit';
import * as dotenv from 'dotenv';
dotenv.config();
const { DATABASE_URL } = process.env;
if (!DATABASE_URL) {
throw new Error('No url');
}
export default {
schema: './src/lib/db/schema.ts',
out: './migrations',
driver: 'pg',
dbCredentials: {
connectionString: DATABASE_URL
}
} satisfies Config;

This is configured to use postgres , if you use other db , refer this.

Here you can see that i’ve used dotenv , the reason for this is , you run your migration scripts without vite or sveltekit so by default you don’t load your environmental variables.

And also don’t forget to add dotenv to your project.

pnpm add -D dotenv

Now , lets add the scripts to out package.json for easily running our scripts

  "studio": "drizzle-kit studio --config drizzle.config.ts",
"generate": "drizzle-kit generate:pg --config drizzle.config.ts",
"migrate": "drizzle-kit push:pg --config drizzle.config.ts"

I would add these to my “scripts” of my package.json. This is how my package.json looks after adding the scripts.

{
"name": "drizzle-svletekit",
"version": "0.0.1",
"private": true,
"scripts": {
"dev": "vite dev",
"build": "vite build",
"preview": "vite preview",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
"studio": "drizzle-kit studio --config drizzle.config.ts",
"generate": "drizzle-kit generate:pg --config drizzle.config.ts",
"migrate": "drizzle-kit push:pg --config drizzle.config.ts"
},
"devDependencies": {
"@sveltejs/adapter-auto": "^2.0.0",
"@sveltejs/kit": "^1.27.4",
"dotenv": "^16.3.1",
"drizzle-kit": "^0.20.4",
"svelte": "^4.0.5",
"svelte-check": "^3.6.0",
"tslib": "^2.4.1",
"typescript": "^5.0.0",
"vite": "^4.4.2"
},
"type": "module",
"dependencies": {
"drizzle-orm": "^0.29.0",
"postgres": "^3.4.3"
}
}

Now after this , we will be able to do

Run Schema Generation — pnpm run generate

Push the Schema changes to Db — pnpm run migrate

Open up a nice db Ui for development — pnpm run studio

If you use postgres you need to install pg driver . if you would like to use studio which can be done with

pnpm add -D pg

Now you have a Typesafe and enjoyable way to perform Operations on you Db , I would extend my setup with zod for extended support but it’s my personal preference , you can add more and more configuration according to you needs.

Lets run our sample query with SSR .

// +page.server.ts
import { db } from '$lib/db/db.server';
import { myTable } from '$lib/db/schema';
import type { PageServerLoad } from './$types';

export const load = (async () => {
const result = await db.select().from(myTable)
return {
result
};
}) satisfies PageServerLoad;
//+page.svelte
<script lang="ts">
export let data
console.log(data.result);
</script>

<p>If you are here , you successfully setup DRIZZLE ORM with SVELTEKIT</p>

If you hover over your fetched data ,You can see all your data is completely typesafe.

Conclusion

Drizzle + Sveltekit + Zod + Trpc , a combo made in heaven these tools utilize typescript to it best and give us the best DX.

Drizzle is a really powerful ORM with Extended features, It has grown to be my personal favourite and goto choice of ORM if i’m building anything using typescript.

You can find the sample project here.

--

--