Skip to content

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:

from your project root
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.

tsconfig.json
{
"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.

  1. 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.

  2. Install the packages with your package manager of choice

    Terminal window
    npm i drizzle-orm # and your chosen driver(s)
  3. 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.

Terminal window
npm i -D drizzle-kit

Then configure it with drizzle.config.ts

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

package.json
{
...
"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
  1. Create a project on Infisical

  2. Add a DB_URL variable to your project

  3. Follow the Infisical CLI installation instructions to get it set up on your machine

  4. Login to Infisical on your machine

    Terminal window
    infisical login
  5. Initialize Infisical in your app

    from your project root
    infisical init
  6. Update the package.json scripts to use Infisical

    package.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
Terminal window
npm i -D dotenv-cli
package.json
{
...
"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
Terminal window
npm i -D @dotenvx/dotenvx
package.json
{
...
"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

Terminal window
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.

Terminal window
npm i server-only