Introduction

d1-studio is a local-first database studio built natively for Cloudflare D1. It runs as a Next.js dev server alongside your project — no separate database GUI to install, no cloud account to configure, no extra dependencies beyond what you already have.

Point it at any project with a wrangler.toml and it auto-discovers your D1 bindings, connects to the local SQLite file that Wrangler manages, and opens a full-featured studio in your browser.

d1-studio has not been tested on Windows yet. If you run into issues, please reach out on Twitter/X at @heykarenrc.

FreeTable browser, SQL editor, schema viewer, migrations, import/export
ProRemote sync, time travel, multi-database switcher, query collections

Getting started

Run d1-studio from the root of any Cloudflare Workers project that has at least one D1 binding in its Wrangler config. Node 18 or later is required.

Install

$ npm install -g d1s

Update

$ npm install -g d1s@latest

Run

$ d1studio

d1-studio will locate your wrangler.toml (or wrangler.json / wrangler.jsonc), read your D1 binding names, connect to the local SQLite database that Wrangler writes to under .wrangler/state/v3/d1/, and opens the studio at http://localhost:4000.

The studio process exits when you close the terminal. Your Wrangler config and database files are never modified.

Requirements

Node.js18 or later
Wrangler configwrangler.toml · wrangler.json · wrangler.jsonc
D1 bindingat least one [[d1_databases]] entry

Typical wrangler.toml

name = "my-worker"
compatibility_date = "2024-01-01"

[[d1_databases]]
binding = "DB"
database_name = "my-database"
database_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

d1-studio reads the database_name field to identify databases and the binding field to distinguish multiple bindings. The database_id is used by Pro features (remote sync and time travel) when calling the Cloudflare API.


Table browser

Click any table in the left sidebar to open it in the table browser. All rows are loaded with pagination. You can filter columns, sort by any field, and edit values inline by clicking a cell.

Filtering

Use the + Filter toolbar button to add column-level filters. Multiple filters are combined with AND logic. Filters are applied in the browser and do not modify the underlying SQL query sent to the database.

Inline editing

Click any cell to edit it in place. Press Enter to save or Escape to cancel. Changes are written immediately via a parameterised UPDATE statement — there is no staging or batch-commit step.

Export

Use the Export button to download the current table (or the current filtered view) as JSON or CSV. Import a CSV or JSON file via Import — a column-mapping dialog lets you match file columns to table columns before inserting.

Relationship viewer

Foreign key cells are underlined and clickable. Clicking a FK value opens a slide-in drawer showing the referenced row from the related table, so you can inspect relationships without leaving the current view.


SQL editor

The SQL editor lets you run arbitrary SQL against your local D1 database. Results appear in a table below the editor. The editor supports syntax highlighting and multi-statement execution.

Query history

Every query you run is saved to local history. Use the history panel to recall and re-run previous queries. History is stored in the browser and persists across sessions.

Tips

SELECT *Start with SELECT to inspect data safely before writing mutations.
PRAGMA table_info(name)Get column names and types for any table.
EXPLAIN QUERY PLANPrefix any SELECT with EXPLAIN QUERY PLAN to see how D1 will execute it.

Schema viewer

The schema viewer shows the structure of every table in your database: column names, types, whether they accept NULL, default values, and primary key membership. Foreign key relationships between tables are shown as connecting lines in the ERD (entity-relationship diagram) view.

The ERD is generated automatically from your live schema — it reflects what is actually in the database, not what is in any migration file. Switch between the ERD and the raw table list using the view toggle.


Migrations

d1-studio integrates with Wrangler's migration convention: SQL files in the migrations/ directory (configurable via migrations_dir in wrangler.toml). Each file is treated as one migration. The migrations view shows all discovered files alongside their status.

AppliedMigration has been run against the local database. Checksum is stored to detect tampering.
PendingMigration file exists but has not yet been applied.
OrphanedMigration appears in the database's history table but no matching file exists — usually means a file was deleted after being applied.

Applying migrations

Click Apply pending to run all pending migrations in order. Each migration is executed as a transaction — if a migration fails, it rolls back and subsequent migrations are not applied.

Migration naming

Wrangler names migrations by timestamp: 0001_create_users.sql, 0002_add_index.sql, etc. d1-studio applies them in lexicographic order, so consistent numeric prefixes are important.

Per-database migration directories

If you have multiple D1 databases, each one can use its own migrations directory by setting migrations_dir in its [[d1_databases]] block. d1-studio respects this setting when browsing migrations, applying them locally, and during push/pull operations.

[[d1_databases]]
binding = "DB"
database_name = "production"
database_id = "xxxxxxxx-..."
migrations_dir = "migrations"

[[d1_databases]]
binding = "ANALYTICS"
database_name = "analytics"
database_id = "yyyyyyyy-..."
migrations_dir = "migrations-analytics"

Remote sync PRO

Remote sync lets you synchronise migrations between your local project and your production Cloudflare D1 database. It uses your existing Wrangler credentials — no separate setup is needed if you have already run wrangler login.

Credentials

d1-studio reads Wrangler's own credential file at startup. If you have run wrangler login (OAuth) or have an api_token in your Wrangler config, remote sync works immediately — no browser prompt, no extra config.

If no credentials are found, d1-studio will print a warning on startup: run wrangler login in your project directory to authenticate.

Pull

Pull fetches the list of migrations already applied on the remote database and downloads any that are missing locally. A preview is shown before anything is written, listing which migration files will be added. An optional Sync remote data step can pull up to 75 rows per table into your local database after the migration pull completes.

Push

Push applies any pending local migration files to the remote database. A preview lists each file and whether it will be applied or skipped (already applied). Only new migrations are run — existing remote data is never deleted. Seed files (*seed*.sql) are automatically excluded from push.


Time travel PRO

Time travel is Cloudflare's built-in point-in-time recovery for D1. Every D1 database automatically retains a continuous bookmark history for 30 days. d1-studio provides a UI to restore your database to any timestamp within that window — no wrangler CLI required.

How to restore

Open the Time travel view from the sidebar. The view loads the current remote snapshot bookmark on mount and refreshes automatically when you switch databases. Select a date and time (or use a quick-pick shortcut), click Refresh preview to confirm the target, then click Restore database. A confirmation dialog is shown before the restore executes, and an undo bookmark is displayed afterwards so you can revert if needed.

Time travel uses your Wrangler credentials — the same ones used for remote sync. It runs wrangler d1 time-travel under the hood, so no separate token setup is required.

Note: time travel operates on the remote D1 database. After restoring, use Pull in the remote sync view to bring the restored state into your local environment.

Limitations

Cloudflare retains bookmarks for up to 30 days. Timestamps older than 30 days cannot be restored. Time travel requires Wrangler credentials with D1 write permissions.


Multi-database switcher PRO

If your wrangler.toml defines more than one D1 binding, d1-studio shows a database switcher in the sidebar. Click the current database name to open a dropdown of all available bindings and switch between them instantly.

[[d1_databases]]
binding = "DB"
database_name = "production"
database_id = "xxxxxxxx-..."
migrations_dir = "migrations"

[[d1_databases]]
binding = "ANALYTICS"
database_name = "analytics"
database_id = "yyyyyyyy-..."
migrations_dir = "migrations"

With the above config, d1-studio detects both bindings and lets you switch between production and analytics without restarting. All views (table browser, SQL editor, schema, migrations) operate on the currently selected database. Remote sync and time travel also scope to the selected database — including using its migrations_dir when pushing or pulling.


Configuration

d1-studio is intentionally zero-config for basic use. The only required setup is a valid Wrangler config file. The options below cover advanced scenarios.

Environment variables

D1_STUDIO_NO_TELEMETRYdefault: 1

Disable all anonymous telemetry. d1-studio sends version, platform, and feature-usage pings by default. No database contents or personal data are ever included.

D1_STUDIO_PORTdefault: 3000

Override the default port the studio listens on.

D1_STUDIO_PROJECT_PATHdefault: /path/to/project

Override the directory d1-studio searches for a Wrangler config. Defaults to the current working directory.

License key

After purchasing Pro, you'll receive a license key by email. Activate it by running:

$ d1studio --license YOUR-LICENSE-KEY

The license is stored in ~/.d1studio/license.json and tied to your machine's hardware fingerprint. To transfer your license to a new machine, deactivate it first from your account dashboard, then activate on the new machine.

Wrangler config auto-discovery

d1-studio searches for a Wrangler config file by walking up the directory tree from the current working directory. It checks for files in this order:

1.wrangler.toml
2.wrangler.json
3.wrangler.jsonc

The first match is used. If no config is found, d1-studio exits with an error.