| 1 | --- |
| 2 | title: Drizzle ORM with Neon |
| 3 | description: Configure Neon projects, branches, committed Drizzle migrations, and direct or pooled connections. |
| 4 | --- |
| 5 | |
| 6 | Use the portable [Drizzle Postgres client](/sql/drizzle/postgres) with Neon; this page configures the database and its connections. For Worker deployment, follow [Add Drizzle ORM](/cloudflare/data/drizzle). |
| 7 | |
| 8 | ## Configure migration generation |
| 9 | |
| 10 | ```typescript |
| 11 | // drizzle.config.ts |
| 12 | import { defineConfig } from "drizzle-kit"; |
| 13 | |
| 14 | export default defineConfig({ |
| 15 | schema: "./src/schema.ts", |
| 16 | out: "./migrations", |
| 17 | dialect: "postgresql", |
| 18 | }); |
| 19 | ``` |
| 20 | |
| 21 | Use a `pg-core` schema as shown in [Drizzle Postgres](/sql/drizzle/postgres#define-the-schema); generation does not need Neon credentials. |
| 22 | |
| 23 | ## Generate and review migrations |
| 24 | |
| 25 | ```sh |
| 26 | bunx drizzle-kit generate |
| 27 | git diff -- src/schema.ts migrations |
| 28 | git status --short |
| 29 | git add src/schema.ts drizzle.config.ts migrations |
| 30 | git diff --cached |
| 31 | git commit -m "Add database migration" |
| 32 | ``` |
| 33 | |
| 34 | Run this when the schema changes, then review and commit the schema, generated SQL, and snapshots together before deploying. The optional [`Drizzle.Schema` resource](/providers/drizzle/schema) is a separate integration, not required for this workflow. |
| 35 | |
| 36 | ## Feed `migrations` from the schema |
| 37 | |
| 38 | ```typescript |
| 39 | // src/Db.ts |
| 40 | import * as Neon from "alchemy/Neon"; |
| 41 | import * as Effect from "effect/Effect"; |
| 42 | |
| 43 | export const NeonDb = Effect.gen(function* () { |
| 44 | const project = yield* Neon.Project("app-db", { |
| 45 | region: "aws-us-east-1", |
| 46 | }); |
| 47 | const branch = yield* Neon.Branch("app-branch", { |
| 48 | project, |
| 49 | migrations: "./migrations", |
| 50 | }); |
| 51 | return { project, branch }; |
| 52 | }); |
| 53 | ``` |
| 54 | |
| 55 | With `Neon.providers()` registered in your Stack, `Neon.Branch` applies the committed directory; `Neon.Project` accepts the same prop for its default branch. [Neon migrations](/neon/data/migrations) covers transaction and tracking behavior. |
| 56 | |
| 57 | ## Iterate |
| 58 | |
| 59 | ```sh |
| 60 | bun alchemy deploy |
| 61 | ``` |
| 62 | |
| 63 | Deploy the committed files; this configuration does not generate SQL during deployment. If you already use `drizzle-kit migrate`, keep that application workflow unless you deliberately choose Alchemy-managed migrations; see [migration ownership](/sql/drizzle/migrations). |
| 64 | |
| 65 | ## Connect at runtime |
| 66 | |
| 67 | ```typescript |
| 68 | import * as Cloudflare from "alchemy/Cloudflare"; |
| 69 | |
| 70 | export const Hyperdrive = Effect.gen(function* () { |
| 71 | const { branch } = yield* NeonDb; |
| 72 | return yield* Cloudflare.Hyperdrive.Connection("app-hyperdrive", { |
| 73 | origin: branch.origin, |
| 74 | dev: branch.pooledOrigin, |
| 75 | }); |
| 76 | }); |
| 77 | ``` |
| 78 | |
| 79 | Use `branch.origin` when Hyperdrive handles pooling, and `branch.pooledOrigin` for local development that bypasses Hyperdrive. Other runtimes can use `connectionUri` or `pooledConnectionUri`; [Connections](/neon/data/connections) covers their configuration, and the [Cloudflare walkthrough](/cloudflare/data/drizzle) owns Worker bindings and queries. |
| 80 | |
| 81 | ## Where next |
| 82 | |
| 83 | Read [Preview branches per PR](/neon/guides/preview-branches) for branch provisioning, or [SQL databases](/sql/databases) for client discovery. The [Project](/providers/neon/project) and [Branch](/providers/neon/branch) references cover resource options. |