Migrations
prisma migrate dev, db push, and db pull all work under Bun with no extra
setup.
Setup
Point prisma.config.ts at your database:
import { defineConfig } from 'prisma/config'
export default defineConfig({
schema: 'schema.prisma',
datasource: { url: 'file:./dev.db' },
})
Then run the commands with bunx:
bunx prisma migrate dev --name init
bunx prisma db push
bunx prisma db pull
What actually connects
Worth being precise about, because it is easy to assume otherwise: in Prisma 7.9
the CLI does not migrate through this adapter. It reads datasource.url from
prisma.config.ts and uses its own SQLite handling. PrismaConfig has no adapter
field, and the error Prisma raises for a schema-level url directs you to pass
adapter to the PrismaClient constructor — a runtime concern.
The practical consequence is good: migrations work under Bun without involving the adapter at all, so there is nothing extra to configure.
The adapter still implements SqlMigrationAwareDriverAdapterFactory, including
connectToShadowDb, because that is the interface the schema engine consumes and
it may be wired differently in future versions. It is implemented and tested; it
is simply not on the CLI path today.
Applying a schema in tests
Since the CLI owns migrations, tests that need a schema have two straightforward options.
Replay the committed migration SQL:
const statements = readFileSync('migrations/20260101000000_init/migration.sql', 'utf8')
.split(';')
.map((statement) => statement.trim())
.filter((statement) => statement.length > 0)
for (const statement of statements) {
await prisma.$executeRawUnsafe(statement)
}
This is what this project’s own end-to-end suite does, so the tests exercise
exactly what prisma migrate produced rather than a hand-maintained copy.
Or run db push against a temporary file once, and copy that file per test.
Shadow databases
If a future Prisma version does route migrations through the adapter, the shadow database is configurable:
new PrismaBunSQLite(
{ url: 'file:./dev.db' },
{ shadowDatabaseUrl: ':memory:' },
)
The default ':memory:' is a good fit for SQLite: always empty, no cleanup, no
permissions to arrange.