npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@theokit/plugin-db-drizzle

v0.7.0

Published

drizzle-kit helpers for TheoKit apps: builds the drizzle-kit command lines and the drizzle.config.ts for your own db scripts, plus a drizzle-kit studio tab descriptor. Registers nothing at runtime.

Readme

@theokit/plugin-db-drizzle

drizzle-kit helpers for TheoKit apps. You declare your database once with drizzleDb(...), and the package turns that declaration into the drizzle-kit command lines and the drizzle.config.ts your own db script runs.

What this package does not do. It registers nothing at runtime: drizzleDb(...).register() is empty, so adding the plugin to theo.config.ts connects to no database, adds no CLI command and mounts no devtools tab. It never opens a connection or spawns a process itself. It also does not depend on, wrap or re-export @theokit/orm.

The theokit db migrate | generate | seed commands in the theokit CLI (0.75 and later) are part of TheoKit and do not use this plugin.

What you get

| Export | What it returns | | ------------------------------ | ------------------------------------------------------------------------------------------------------------------------- | | drizzleDb(options) | A plugin object whose options field holds your options with every default filled in. Its register() does nothing. | | buildDbCommands(options) | Seven command descriptors (generate, migrate, push, studio, reset, seed, check) for your own script to run. | | renderDrizzleConfig(options) | The text of a drizzle.config.ts, for the verbs drizzle-kit only drives through --config. | | buildDevtoolsTab(options) | A { id, label, studioUrl, mount } descriptor that frames drizzle-kit studio, for an overlay of your own. |

Pass drizzleDb(...).options to the three builders. They take the resolved shape, and a hand-written object missing a field builds an argv with undefined in it instead of failing.

Install

pnpm add @theokit/plugin-db-drizzle drizzle-orm
pnpm add -D drizzle-kit

drizzle-orm is a peer because your schema file imports it; this package does not. drizzle-kit is an optional peer: only the commands you build need it.

Declare the database

import { drizzleDb } from '@theokit/plugin-db-drizzle'

export const db = drizzleDb({
  driver: 'postgres',
  url: process.env.DATABASE_URL,
  schemaPath: './db/schema.ts',
  migrationsPath: './db/migrations',
})

Listing db under plugins in theo.config.ts is allowed and changes nothing at runtime. Keep it in a module your scripts can import.

Options reference

| Option | Type | Default | Notes | | ---------------- | ----------------------------------- | -------------------------------- | ---------------------------------------------------------- | | driver | 'sqlite' \| 'postgres' \| 'mysql' | (required) | Mapped to drizzle-kit's --dialect | | url | string | (none) | Connection URL; never written to the config or an argv | | urlEnv | string | 'DATABASE_URL' | Env var the generated config reads the URL from | | schemaPath | string | './db/schema.ts' | Your drizzle schema file | | migrationsPath | string | './db/migrations' | Where generate writes migrations | | configPath | string | './.theokit/drizzle.config.ts' | Where your script writes renderDrizzleConfig(...) | | seedScript | string | (none) | Script the seed verb runs; drizzle-kit has no seed | | resetScript | string | (none) | Script the reset verb runs; drizzle-kit has no reset | | studioHost | string | 'localhost' | Host for studio and the devtools tab | | studioPort | number | 4983 | Port for studio and the devtools tab | | devtoolsTab | boolean | true | Carried on options for your own wiring; nothing reads it |

A db script

Each command says how to run it in kind:

  • drizzle-kit: run drizzle-kit with buildArgs().
  • drizzle-kit-with-config: write renderDrizzleConfig(options) to options.configPath first, then run drizzle-kit with buildArgs(). migrate, studio and push run only through --config.
  • user-script: buildArgs() returns your seedScript or resetScript; run that. It throws when the script is not configured.

Every command also carries env: { [urlEnv]: url } when you passed url. The generated config reads process.env[urlEnv] when drizzle-kit loads it, so the URL value is never written to the file or to an argv. Add env to the environment of the process you spawn.

reset also sets requiresForce, so the script below refuses it without --force.

// scripts/db.ts
import { mkdirSync, writeFileSync } from 'node:fs'
import { dirname } from 'node:path'
import { spawnSync } from 'node:child_process'
import { buildDbCommands, drizzleDb, renderDrizzleConfig } from '@theokit/plugin-db-drizzle'

const { options } = drizzleDb({ driver: 'postgres', url: process.env.DATABASE_URL })
const [verb, ...rest] = process.argv.slice(2)
const cmd = buildDbCommands(options).find((c) => c.verb === verb)
if (!cmd) throw new Error(`unknown verb ${verb}`)
if (cmd.requiresForce && !rest.includes('--force')) throw new Error(`db ${verb} needs --force`)

if (cmd.kind === 'drizzle-kit-with-config') {
  mkdirSync(dirname(options.configPath), { recursive: true })
  writeFileSync(options.configPath, renderDrizzleConfig(options))
}
const [file, args] =
  cmd.kind === 'user-script'
    ? ['npx', ['tsx', ...cmd.buildArgs()]]
    : ['npx', ['drizzle-kit', ...cmd.buildArgs()]]
const result = spawnSync(file, args, { stdio: 'inherit', env: { ...process.env, ...cmd.env } })
process.exit(result.status ?? 1)
{ "scripts": { "db": "tsx scripts/db.ts" } }
pnpm db generate       # drizzle-kit generate: migration from the schema diff
pnpm db migrate        # drizzle-kit migrate, through the generated config
pnpm db push           # drizzle-kit push: schema straight to the database (development)
pnpm db studio         # drizzle-kit studio, through the generated config
pnpm db check          # drizzle-kit check
pnpm db seed           # your seedScript
pnpm db reset --force  # your resetScript

The generated config is rewritten on every run; add .theokit/ to .gitignore.

Devtools tab

buildDevtoolsTab(options) returns a descriptor whose mount(container) appends an <iframe> pointing at http://<studioHost>:<studioPort> (drizzle-kit studio's default is http://localhost:4983). Nothing registers it for you; mount it in an overlay you own:

import { buildDevtoolsTab, drizzleDb } from '@theokit/plugin-db-drizzle'

const tab = buildDevtoolsTab(drizzleDb({ driver: 'sqlite', url: ':memory:' }).options)
tab.mount(document.getElementById('panel')!)

License

Apache-2.0