vb_migrations

Collections, for the half of the data the admin panel and the SDK own. It is the counterpart of Void's db/, which holds the app's own tables, and the two live side by side on purpose.

Which database gets what

db/, in Drizzlevb_migrations/, as collections
Reached byYour own code, typed end to endThe SDK, the admin panel, and hooks
RulesWhatever your routes enforceAPI rules, per collection, changeable without a deploy
Good forInternal tables: sessions, jobs, anything nobody outside the app should seeContent and user data: the things people read, write and administer

Both live in the same database. Most apps want both, and the question to ask of any table is who else needs to touch it. If the answer is only your code, it is a Drizzle table. If it is the panel, the SDK or another client, make it a collection.

A migration

The format is the same as a project's pb_migrations, and the reference path points into the generated instance rather than a local pb_data:

/// <reference path="../.voidbase/pb_data/types.d.ts" />

migrate((app) => {
  const posts = new Collection({
    type: "base",
    name: "posts",
    listRule: "published = true",
    createRule: "@request.auth.id != ''",
    updateRule: "@request.auth.id = author.id",
    fields: [
      { name: "title", type: "text", required: true, max: 200 },
      { name: "body", type: "editor" },
      { name: "published", type: "bool" },
      { name: "author", type: "relation", required: true, collectionId: app.findCollectionByNameOrId("users").id, maxSelect: 1 },
    ],
  });
  app.save(posts);
}, (app) => {
  app.delete(app.findCollectionByNameOrId("posts"));
});

Name files so they sort in the order they should run. They are copied into the generated instance on build, beside the ones generated from your Drizzle migrations, and applied in that order on the first request after a deploy, each recorded so it runs once.

After bun run build, inside .voidbase/pb_migrations/:

  • 1725712800_posts.js: your file, copied
  • 0001_initial.void.js: one per Drizzle migration in db/migrations/, applied and recorded like any other

Getting the first one written

Build and run the app, design the collections in the admin panel at /_/, then export them from the panel's Collections screen and save the result as a migration. After that, every change is a new file, and the schema travels with the repository.

Found something wrong on this page?

Fix it yourself. The link below opens this file in GitHub's editor and forks the repository for you if you need one, and your change becomes a pull request without leaving the browser.