prisma/prisma
Migrate flow
prisma migrate dev and friends, as a cross-package narrative. The implementation lives in @prisma/migrate; the engine binary lives in prisma-engines.
Components
| Layer | Package / location | Responsibility |
|---|---|---|
| User command | prisma migrate dev (typed in shell) |
Entry |
| CLI dispatch | packages/cli/src/CLI.ts |
Routes to MigrateCommand |
| Migrate namespace | packages/migrate/src/commands/MigrateCommand.ts |
Routes to subcommand (MigrateDev.ts) |
| Subcommand | packages/migrate/src/commands/MigrateDev.ts |
Orchestrates the dev workflow |
| Migrate facade | packages/migrate/src/Migrate.ts |
High-level RPC client |
| Engine transport | packages/migrate/src/SchemaEngineCLI.ts (default) or SchemaEngineWasm.ts |
JSON-RPC over stdio or in-process Wasm |
| Engine binary | schema-engine (downloaded by @prisma/engines) |
Schema diffing + DDL generation |
| Database | (user-configured via prisma.config.ts) |
Target |
End-to-end sequence
sequenceDiagram
participant User
participant CLI as packages/cli
participant Cmd as MigrateDev.ts
participant Migrate as Migrate.ts
participant Engine as SchemaEngineCLI
participant Bin as schema-engine binary
participant DB
User->>CLI: prisma migrate dev
CLI->>Cmd: parsed args + config
Cmd->>Migrate: instantiate
Migrate->>Engine: spawn (subprocess)
Cmd->>Migrate: devDiagnostic
Migrate->>Engine: rpc devDiagnostic
Engine->>Bin: stdin JSON
Bin->>DB: introspection queries
DB-->>Bin: state
Bin-->>Engine: stdout JSON
Engine-->>Migrate: typed result
alt schema drifted
Cmd->>Migrate: evaluateDataLoss
Migrate->>Engine: rpc evaluateDataLoss
Engine-->>Cmd: warnings + actions
Cmd->>User: prompt for confirmation
end
Cmd->>Migrate: createMigration
Migrate->>Engine: rpc createMigration
Engine-->>Migrate: SQL files written to ./prisma/migrations
Cmd->>Migrate: applyMigrations
Migrate->>Engine: rpc applyMigrations
Engine->>DB: DDL
DB-->>Engine: ok
Engine-->>Migrate: applied list
Cmd->>User: success
Cmd->>CLI: spawn `prisma generate` (regenerate Client)Each subcommand follows a different sub-sequence but uses the same RPC primitives:
migrate deploy→applyMigrationsonly (no diffing, no prompts)migrate diff→diffbetween two sources (file/db)migrate reset→resetthen re-applydb push→schemaPush(no migration history)db pull→introspect
RPC contract
Defined in packages/migrate/src/types.ts. Methods include:
applyMigrations(params)— apply pending migration filescreateMigration(params)— diff schema vs migrations, write a new migration filedevDiagnostic(params)— analyze drift / out-of-sync statediff(params)— emit a diff between two sourcesevaluateDataLoss(params)— check if pending changes lose datagetDatabaseVersion(params)— DB version stringintrospect(params)— pull schema from databasemarkMigrationApplied/markMigrationRolledBack— fix state without applyingreset(params)— drop everythingschemaPush(params)— push schema directly (db push)
The transport (SchemaEngineCLI / SchemaEngineWasm) handles message framing; the dispatcher in Migrate.ts exposes typed methods.
Why two transports
SchemaEngineCLIspawns the binary as a subprocess and exchanges JSON-RPC messages over stdio. Default on Node platforms where spawning is cheap.SchemaEngineWasmruns the same logic in-process via Wasm. Used in restricted environments (e.g., Studio embedded in a non-Node host).
Both implement the same interface (SchemaEngine.ts); subcommands don't see the difference.
Generation step
migrate dev finishes by re-running prisma generate so the user's generated client picks up new tables/columns. The current implementation spawns the CLI as a subprocess.
Dev fixture
packages/migrate/schema.prisma and packages/migrate/prisma.config.ts (in the package root) define a minimal schema used by pnpm exec tsx packages/migrate/src/bin.ts for ad-hoc development. From CONTRIBUTING.md:
cd packages/migrate/fixtures/blog— it's a minimal project that can be used to try things out Then modify some code../../src/bin.ts migrate devfor runningprisma migrate devcommand. (It will usetsx)
Tests
Migrate tests live in packages/migrate/src/__tests__/ and use the helper context in __tests__/__helpers__/context.ts. The harness:
- Sets up a virtual filesystem rooted at a temp directory
- Lets you swap config files via
ctx.setConfigFile(...) - Lets you override datasource URLs via
ctx.setDatasource(...)/ctx.resetDatasource() - Captures stdio for assertions
MigrateDev.test.ts (1,794 lines) is the largest of these — it's the regression net for the dev workflow.
See also
packages/migratefor per-subcommand implementation pointers- Schema Engine RPC for the deeper transport detail
packages/enginesfor how the engine binary gets onto diskpackages/configforprisma.config.ts
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.