Installation
Everything you need before you can start using wunshot effectively
Prerequisites
A Typescript App
You can set up a typescript project with any major framework.
You are not limited to frontend frameworks or frameworks at all. See how to run typescript with Node.js
Bun, Deno, and workerd also give TypeScript first-class support.
A (PostgreSQL) Database
You must have access to a database. If you don’t, you can start with the PostgreSQL Download Page or Detailed installation guides or see How to Use the Postgres Docker Official Image. Another good option for local development that can manage multiple versions/instances of PostgreSQL without the overhead of docker is DBngin.
There are numerous hosting/cloud options for PostgreSQL beyond the scope of this guide.
Once your database is set up, you should have connection URL that looks something like:
postgresql://USER:PASSWORD@HOST:PORT/DATABASE_NAME?PARAM_NAME=PARAM_VALUE
Read more about connection URIs
Add your connection URL to your project’s .env
file or secrets manager.
Create your folder structure
Directoryapp/
- …
Directorydb
Directoryhelpers/
- …
Directorymigrations/ auto-generated by
drizzle-kit
- …
Directorymodels
Directoryusers
- queries.ts
- schema.ts
- validations.ts
Directoryops
- …
- index.ts
- drizzle.config.ts
Run this snippet to auto-generate the structure:
mkdir -p db/helpers db/models/users db/ops && touch db/index.ts db/models/users/queries.ts db/models/users/schema.ts db/models/users/validations.ts drizzle.config.ts
Set up TypeScript
Alias #
to the db
directory.
{ "compilerOptions": { "strict": true, // recommended "noUncheckedIndexedAccess": true, // recommended ... "paths": { "#/*": ["./db/*"], "@/*": ["./*"] } }}
Set up Drizzle
Database Connections with Drizzle ORM
Follow the installation instructions for PostgreSQL on the Drizzle ORM website for detailed directions.
-
Select your driver(s)
Select a driver based on your database provider or hosting setup. Some providers may use their own drivers, while others may rely on popular community packages like node-postgres or Postgres.js.
See Drizzle ORM - PostgreSQL for more information about supported ways to connect.
-
Install the packages with your package manager of choice
Terminal window npm i drizzle-orm # and your chosen driver(s) -
Set up your database connection
Here’s an example with the node-postgres driver. Your setup may be different.
@/db/index.ts import { drizzle } from "drizzle-orm/node-postgres";const { DB_URL } = process.env;if (!DB_URL) throw new Error("Missing db url");export const db = drizzle({connection: { connectionString: DB_URL },casing: "snake_case",// logger: true,});export const txDb = db; // node-postgres supports transactions, so this is a simple alias
Automatic Migration Generation with Drizzle Kit
Install drizzle-kit
into your devDependencies
with your package manager of choice.
npm i -D drizzle-kit
Then configure it with drizzle.config.ts
import { defineConfig } from "drizzle-kit";
const { DB_URL } = process.env;if (!DB_URL) throw new Error("Missing db url");
export default defineConfig({ dialect: "postgresql", out: "./db/migrations", schema: "./db/models/**/*(schema|view)s.ts", dbCredentials: { url: DB_URL }, casing: "snake_case", // Print all statements verbose: true, // Always ask for confirmation strict: true,});
See the Drizzle Kit Config Reference for more information.
Add package.json
scripts for migrations
{ ... "scripts": { ... "db": "drizzle-kit", "db:drop": "npm run db -- drop", "db:generate": "npm run db -- generate", "db:migrate": "npm run db -- migrate", "db:push": "npm run db -- push", "db:studio": "npm run db -- studio", } ...}
Accessing env variables
Depending on your project setup, you may need to pass environment variables to drizzle-kit explicitly.
If you try to run npm run db:generate
and trigger the Missing db url
error, then try one of the following solutions.
Use a secrets manager
Infisical
-
Create a project on Infisical
-
Add a
DB_URL
variable to your project -
Follow the Infisical CLI installation instructions to get it set up on your machine
-
Login to Infisical on your machine
Terminal window infisical login -
Initialize Infisical in your app
from your project root infisical init -
Update the
package.json
scripts to use Infisicalpackage.json {..."scripts": {..."db": "infisical run -- drizzle-kit","db:drop": "npm run db -- drop","db:generate": "npm run db -- generate","db:migrate": "npm run db -- migrate","db:push": "npm run db -- push","db:studio": "npm run db -- studio",}...}
Read the Infisical Quickstart Guide for more detailed instructions and configuration options.
Use .env
file(s)
Add your DB_URL
to .env.local
:
DB_URL="postgresql://USER:PASSWORD@HOST:PORT/DATABASE_NAME?PARAM_NAME=PARAM_VALUE"
dotenv-cli
npm i -D dotenv-cli
{ ... "scripts": { ... "db": "dotenv -e .env.local -- drizzle-kit", "db:drop": "npm run db -- drop", "db:generate": "npm run db -- generate", "db:migrate": "npm run db -- migrate", "db:push": "npm run db -- push", "db:studio": "npm run db -- studio", } ...}
dotenvx
npm i -D @dotenvx/dotenvx
{ ... "scripts": { ... "db": "dotenvx run -f .env.local -- drizzle-kit", "db:drop": "npm run db -- drop", "db:generate": "npm run db -- generate", "db:migrate": "npm run db -- migrate", "db:push": "npm run db -- push", "db:studio": "npm run db -- studio", } ...}
Install Valibot
npm i valibot
(Optional) server-only
If you are using react server components, you should use the server-only package. This can help prevent leaking secrets to the client.
npm i server-only