Seed
A seed script populates sample records when a developer runs npm run db:seed. The seeder creates the test user and org, then calls each linked package’s seed function in turn. If your package has useful dev data (example contacts, a starter mailbox, a demo calendar), ship a seed.
Declaring a seed
Point seed.script at a subpath (no extension) inside the package:
seed: { script: 'seed' },
And expose the module in package.json:
{
"exports": {
"./seed": "./seed.ts"
}
}
The seed function
Default-export an async function that takes a PocketBase client and a context object:
import type PocketBase from 'pocketbase'
interface SeedContext {
user: { id: string; email: string; name: string }
org: { id: string }
userOrg: { id: string }
}
export default async function seed(pb: PocketBase, { org, userOrg }: SeedContext) {
await pb.collection('example_items').create({
title: 'Sample item',
org: org.id,
created_by: userOrg.id,
})
}
pb is already authenticated as the superuser, so you can write to any collection. The context exposes the three IDs you’ll almost always need:
user.id- the test user record.org.id- the test org. Use this for anyorgrelation field.userOrg.id- the membership record linking the user to the org. Use this forcreated_byfields in packages that track per-org authorship.
The seeder runs your seed once per invocation. The database is wiped before seeding, so you don’t need idempotency guards - write records straight through.
Keep seeds small
A seed exists so a developer can open the UI and see something. A handful of rows per collection is plenty - enough to exercise list views, navigation, and empty-state transitions. Avoid pulling in large fixture files or generating thousands of records; that’s what Playwright factory helpers are for.
If you need multiple related records, create parents first and feed their IDs into children. Wrap unrelated groups in functions so the seed file stays readable:
export default async function seed(pb: PocketBase, ctx: SeedContext) {
await seedLabels(pb, ctx)
await seedExampleItems(pb, ctx)
}
The generator emits lib/generated/package-seeds.ts, which maps package slugs to their default-exported functions. scripts/seed-db.ts imports that map and iterates it after creating the test user and org. You don’t interact with the generated file directly.