Skip to content

Unlimited seats on Netlify Pro for $20/month → Learn more 👥

Local development

When you run your application locally with the Netlify CLI or the Netlify Vite plugin, Netlify Database just works.

We include a real Postgres-compatible database for local development that mirrors the production environment. Your code talks to it the same way it talks to the production database, through the @netlify/database package or any Postgres driver.

Pick the option that matches how you run your project locally. Whichever you choose, the rest of the workflow on this page (applying migrations, inspecting state, resetting) is identical — the netlify database CLI commands discover the running local database in either case.

Run the Netlify dev server from the root of your project:

Terminal window
netlify dev

The CLI starts the local database as part of netlify dev and shuts it down when the dev server stops. Your functions, edge functions, and frameworks have access to the database immediately, with no extra configuration.

If your project uses Vite, you can run a Netlify-emulated dev environment — including the local database — directly from the Vite dev server, without invoking netlify dev. Install @netlify/vite-plugin and add it to your Vite config:

Terminal window
npm install --save-dev @netlify/vite-plugin
vite.config.ts
import { defineConfig } from "vite";
import netlify from "@netlify/vite-plugin";
export default defineConfig({
plugins: [netlify()],
});

Then start Vite as you normally would:

Terminal window
npm run dev

The plugin starts the local database alongside the Vite dev server and exposes it to your code.

It uses the same engine as netlify dev, so the data, migrations, and connection details are interchangeable between the two — you can switch back and forth without losing state.

Unlike the production environment, where migrations are applied automatically at the right point in the deploy lifecycle, the local database needs you to apply the migrations yourself. This gives you full control over the development lifecycle, letting you apply and undo migrations whenever you need.

To apply any local migrations, run netlify database migrations apply:

Terminal window
netlify database migrations apply

To scaffold a new migration, use netlify database migrations new:

Terminal window
netlify database migrations new --description "add users table"

To pull the migrations applied on a remote branch (for example, after another contributor has shipped a migration to production), use netlify database migrations pull:

Terminal window
netlify database migrations pull

To see the current state of the local database — whether it’s enabled, the connection string, and which migrations are applied or pending — use netlify database status:

Terminal window
netlify database status

To run a query interactively, use netlify database connect:

Terminal window
netlify database connect

This opens an interactive SQL REPL against the local database. To run a single query and exit:

Terminal window
netlify database connect --query "SELECT * FROM users LIMIT 10"

If you want to start over with a clean database, use netlify database reset:

Terminal window
netlify database reset

This drops every schema and table; it only affects the local database, never production or deploy preview branches.

If you want to discard local migrations that haven’t been applied anywhere yet (for example, an experimental migration you no longer want to ship), use netlify database migrations reset:

Terminal window
netlify database migrations reset

Because the local database speaks the Postgres wire protocol, you can connect from any Postgres-compatible tool — psql, pgAdmin, DataGrip, TablePlus, and others — while netlify dev is running.

Get the connection details with:

Terminal window
netlify database connect --json

Use the connection string with the tool of your choice. For example, with psql:

Terminal window
psql "$(netlify database connect --json | jq -r .connection_string)"

The same emulator that powers netlify dev and the Vite plugin is available as a standalone library, which is useful for automated tests that need a real Postgres instance — for example, integration tests that exercise your data access layer without spinning up Docker or hitting a shared development database.

You have two entry points depending on how much of the Netlify environment you need.

Use the @netlify/database-dev module when you just need a Postgres database in your tests, with no functions, edge functions, or other Netlify primitives.

Install the package:

Terminal window
npm install --save-dev @netlify/database-dev

Then start a database from your test setup and tear it down when you’re done:

db.test.ts
import { NetlifyDB } from "@netlify/database-dev";
import { Client } from "pg";
import { afterAll, beforeAll, expect, test } from "vitest";
let db: NetlifyDB;
let connectionString: string;
beforeAll(async () => {
db = new NetlifyDB();
connectionString = await db.start();
await db.applyMigrations("./netlify/database/migrations");
});
afterAll(async () => {
await db.stop();
});
test("inserts and reads a user", async () => {
const client = new Client({ connectionString });
await client.connect();
await client.query("INSERT INTO users (name) VALUES ($1)", ["Ada"]);
const { rows } = await client.query("SELECT name FROM users");
expect(rows).toEqual([{ name: "Ada" }]);
await client.end();
});

By default, the database is in-memory and uses a random free port. Pass options to control either:

  • directory — persist data to disk under the given path (omit for in-memory)
  • port — listen on a fixed port (defaults to a random one)
  • logger — a function used to log internal messages (defaults to console.log)

Use the @netlify/dev package when your tests need more than the database — for example, end-to-end tests that hit a Netlify Function which in turn queries the database. This is the same NetlifyDev engine that the CLI and Vite plugin use, exported as a library.

Terminal window
npm install --save-dev @netlify/dev
import { NetlifyDev } from "@netlify/dev";
const netlifyDev = new NetlifyDev({
projectRoot: "./fixtures/my-project",
});
await netlifyDev.start();
// `NETLIFY_DB_URL` is now set in the runtime; functions, edge functions,
// and any other code under test can read it as they would in production.
// ...run your tests...
await netlifyDev.stop();

The local database is a faithful Postgres environment for day-to-day development, but a few things to keep in mind:

  • It runs on a single local process, so it’s not the right place to load-test or stress-test production-shaped workloads
  • Database branches are a deploy-time concept; locally you have one database that all your code targets
  • Auto-scale and sleep settings don’t apply locally — those are runtime settings on Netlify’s managed Postgres