Enabling easy Prisma usage with PGlite. This includes a runtime adapter helper and a CLI Prisma wrapper:
CLI
prisma migrate dev
with a PGlite database.prisma migrate reset
with a PGlite database.prisma
CLI.adapter helper
prisma db push
but lacking the ability to apply new migrations to an existing PGlite database).See the full reference docs at https://electrovir.github.io/prisma-pglite
npm i prisma-pglite
Set the driverAdapters
preview feature in your schema.prisma
:
generator client {
provider = "prisma-client-js"
previewFeatures = ["driverAdapters"]
}
Use createPgliteAdapter
:
import {PrismaClient} from '@prisma/client';
import {createPgliteAdapter} from 'prisma-pglite';
const prismaClient = new PrismaClient({
adapter: await createPgliteAdapter(),
});
Create new migrations with npx prisma-pglite migrate dev
Instead of running Prisma commands like this:
npx prisma migrate dev
Run them like this:
npx prisma-pglite migrate dev
The prisma-pglite
CLI will:
migrate dev
commands so that they work without running a full Postgres instance.
--schema <schema-path>
to customize the schema location.--name <migration-name>
to provide the migration name inline (otherwise the CLI will prompt you for one).--migrations <migrations-dir-path>
to customize the location of your migrations
folder.source.snapshot
(customizable with --snapshot <snapshot-file-name>
) file inside each migration. You must keep and commit this file otherwise this command will not work in the future (this file is used to keep track of migration progress instead of a postgres instance, as Prisma normally uses).migrate reset
commands so that they work with a PGlite database.
--schema <schema-path>
to customize the schema location.--database <pglite-db-parent-dir-path>
to customize the location of your PGlite database that needs to be reset.--no-hints
to the prisma generate
command.All CLI commands are also accessible via the exported API:
migrate dev
:
import {createPgliteMigration} from 'prisma-pglite';
await createPgliteMigration({migrationName: 'my migration'});
migrate reset
:
import {resetPgliteDatabase} from 'prisma-pglite';
await resetPgliteDatabase();
the whole CLI:
import {runPrisma} from 'prisma-pglite';
await runPrisma(['migrate dev']);
await runPrisma(['generate']);
Use this when instantiating your PrismaClient
instance to connect to or create a PGlite database:
import {PrismaClient} from '@prisma/client';
import {join} from 'node:path';
import {createPgliteAdapter} from 'prisma-pglite';
const mySchemaPath = join('packages', 'backend', 'prisma', 'schema.prisma');
const prismaClient = new PrismaClient({
adapter: await createPgliteAdapter({
schemaFilePath: mySchemaPath,
}),
});
NOTE: createPgliteAdapter
can only push your schema to new PGlite databases. Thus, you'll need to reset your dev database whenever you create a new migration (I suggest investing in a seed script to workaround this and make your dev experience more consistent in general).
See the type PgliteAdapterParams
for more details on customizing createPgliteAdapter
.
Make sure that you have the driverAdapters
preview feature enabled in your schema.prisma
. If you don't enable this, your PrismaClient
constructor won't have an adapter
parameter available.
generator client {
provider = "prisma-client-js"
previewFeatures = ["driverAdapters"]
}
By default, the pgliteDirPath
parameter of createPgliteAdapter
expects multiple PGlite database to exist within itself. The default database will be in ${pgliteDirPath}/dev
and all test database (triggered by passing in the testContext
parameter) will be in ${pgliteDirPath}/${testName}
. This structure can be ignored entirely by instead setting the directDatabaseDirPath
parameter, but then you lose automatic test database paths.
Create a new migration with some flags:
npx prisma-pglite migrate dev --schema packages/backend/prisma/schema.prisma --name 'add user table'
Reset your PGlite database
npx prisma-pglite migrate reset --database .config/pglite-db
Customize the PGlite adapter:
import {PrismaClient} from '@prisma/client';
import {join} from 'node:path';
import {createPgliteAdapter} from 'prisma-pglite';
const mySchemaPath = join('packages', 'backend', 'prisma', 'schema.prisma');
const prismaClient = new PrismaClient({
adapter: await createPgliteAdapter({
schemaFilePath: mySchemaPath,
pgliteDirPath: join('.dev', 'pglite'),
}),
});
Create a fresh and super fast PGlite database instance for each test:
import {describe, it} from '@augment-vir/test';
import {PrismaClient} from '@prisma/client';
import {join} from 'node:path';
import {createPgliteAdapter} from 'prisma-pglite';
const mySchemaPath = join('packages', 'backend', 'prisma', 'schema.prisma');
describe('my test', () => {
it('connects to the database', async (testContext) => {
const prismaClient = new PrismaClient({
adapter: await createPgliteAdapter({
schemaFilePath: mySchemaPath,
pgliteDirPath: join('.dev', 'pglite'),
test: testContext,
}),
});
});
});