Skip to content
VibORM
Esc
navigateopen⌘Jpreview
On this page

Filesystem Storage

Store migrations as files on the local filesystem (default storage driver)

Quick Start

import { createMigrationClient } from "viborm/migrations";
import { createFsStorageDriver } from "viborm/migrations/storage/fs";

const storage = createFsStorageDriver("./migrations");

const migrations = createMigrationClient(client, {
  storageDriver: storage,
});

Configuration

const storage = createFsStorageDriver(baseDir);
Parameter Type Description
baseDir string Base directory for migration files

The baseDir should be an absolute path or relative to the current working directory.

Directory Structure

migrations/                    # baseDir
├── 0000_initial.sql          # First migration
├── 0001_add-users.sql        # Second migration
├── 0002_add-posts.sql        # Third migration
└── meta/                     # Metadata directory
    ├── _journal.json         # Migration index
    ├── _snapshot.json        # Current schema snapshot
    ├── _down/                # Down migrations
    │   ├── 0000_initial.sql
    │   ├── 0001_add-users.sql
    │   └── 0002_add-posts.sql
    ├── _backup/              # Backups before modification
    └── _archive/             # Archived (squashed) migrations

File Formats

Migration Files

SQL files with statements separated by semicolons:

-- 0001_add-users.sql

CREATE TABLE "users" (
  "id" serial PRIMARY KEY,
  "email" text NOT NULL UNIQUE,
  "name" text,
  "created_at" timestamp DEFAULT NOW()
);

CREATE INDEX "users_email_idx" ON "users" ("email");

Journal File

JSON file tracking all migrations:

{
  "version": "1",
  "dialect": "postgresql",
  "entries": [
    {
      "idx": 0,
      "version": "20240115120000",
      "name": "initial",
      "when": 1705320000000,
      "checksum": "sha256:abc123..."
    },
    {
      "idx": 1,
      "version": "20240116140000",
      "name": "add-users",
      "when": 1705413600000,
      "checksum": "sha256:def456..."
    }
  ]
}

Snapshot File

JSON representation of the current schema:

{
  "tables": [
    {
      "name": "users",
      "columns": [
        { "name": "id", "type": "serial", "nullable": false },
        { "name": "email", "type": "text", "nullable": false }
      ],
      "primaryKey": { "columns": ["id"] },
      "indexes": [],
      "foreignKeys": [],
      "uniqueConstraints": []
    }
  ],
  "enums": []
}

Version Control

Migration files are designed to be committed to git:

# .gitignore - don't ignore migrations!
# migrations/  # DO NOT ADD THIS

# Commit migrations
git add migrations/
git commit -m "Add user table migration"

For the generate/apply/status workflow, see Migrate.

Error Handling

The filesystem driver handles common scenarios:

  • Missing directory: Creates directories automatically on put()
  • Missing file: Returns null on get(), no-op on delete()
  • Permission errors: Throws standard Node.js errors
try {
  await migrations.apply();
} catch (error) {
  if (error.code === "EACCES") {
    console.error("Permission denied - check file permissions");
  }
}

Next Steps

Was this page helpful?