migtool 10.0.0

There is a newer version of this package available.
See the version list below for details.
dotnet tool install --global migtool --version 10.0.0
                    
This package contains a .NET tool you can call from the shell/command line.
dotnet new tool-manifest
                    
if you are setting up this repo
dotnet tool install --local migtool --version 10.0.0
                    
This package contains a .NET tool you can call from the shell/command line.
#tool dotnet:?package=migtool&version=10.0.0
                    
nuke :add-package migtool --version 10.0.0
                    

logo

.NET F# License: Apache2 NuGet Version NuGet Downloads Tests

Migrate is a SQLite-first toolkit: filesystem SQL migrations are the schema source of truth, and mig codegen emits typed F# queries for relations you annotate.

What it does

  1. You write ordered *.sql migrations (applied by file name).
  2. You annotate tables/views with -- mig: comments for the ops you want.
  3. mig codegen (or MigLib.Codegen.generate) applies migrations to a temp DB, introspects schema, and emits one .fs module file per annotated relation into an output directory.
  4. At runtime you call MigLib.migrateScripts and use dbTxn with generated helpers on Microsoft.Data.Sqlite (runtime package only — no codegen dependency).

There is no F#-first schema DSL, no SqlProvider, no DbUp dependency, and no automatic normalization.

Annotation example

-- mig:rel User
-- mig:ops insert, select_by(email), select_by_id
-- mig:ops upsert
-- mig:bool active
-- mig:datetime created_at
CREATE TABLE app_user (
  id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
  email TEXT NOT NULL,
  active INTEGER NOT NULL,
  created_at TEXT NOT NULL
) STRICT;

-- mig:ops select_all, select_one_by(email)
CREATE VIEW active_user AS
  SELECT id, email, created_at FROM app_user WHERE active = 1;

Rules:

  • Unannotated relations generate no F#.
  • Ops are explicit; no ops means no type.
  • Multiple -- mig:ops lines on one relation are merged in order (handy for long lists).
  • Views only allow read ops (select_*); write ops fail at codegen.
  • -- mig:rel Name is optional; otherwise the F# name is derived from the SQL identifier.

See specs/sql_first_rewrite.md for the full design.

Installation

dotnet tool install --global migtool

Library:

dotnet add package MigLib

Codegen

mig codegen \
  --migrations ./Migrations \
  --output ./Stores \
  --namespace MyApp.Db

This writes Stores/User.fs, Stores/ActiveUser.fs, etc. (module MyApp.Db.User, …). Hand-written companions can live alongside generated files; only files marked // <auto-generated /> are deleted when a relation disappears.

From build.fsx / F#:

open MigLib.Codegen

match generate "./Migrations" "./Stores" "MyApp.Db" with
| Ok r ->
    Console.WriteLine(
      "generated "
      + string r.relationCount
      + " relations in "
      + r.outputDir)
    r.generatedFiles |> List.iter (fun p -> Console.WriteLine("  " + p))
| Error e -> failwith e

Runtime

open System
open MigLib
open MyApp.Db

// apply migrations from a directory of *.sql files
do!
  migrateScripts dbPath "./Migrations"
  |> Task.map (function Ok () -> () | Error e -> failwith e)

// use transactions + generated queries (module MyApp.Db.User)
let! user =
  dbTxn dbPath {
    match! User.selectOneByEmail email with
    | Some u -> return u
    | None ->
      let! id =
        User.insert
          { Email = email
            Active = true
            CreatedAt = DateTimeOffset.UtcNow }
      return! User.selectById id |> TxnStep.map Option.get
  }

Packages

Package Role
migtool CLI (mig codegen, mig version)
MigLib Runtime: dbTxn / TxnStep, Query, filesystem migrateScripts (AOT-oriented)
MigLib.Codegen Dev-time generate API (used by CLI and build.fsx)

Local build

dotnet fsi build.fsx -- --target build
dotnet fsi build.fsx -- --target install
cd src && dotnet test

Version

Major version 10 is a greenfield rewrite (SQL-first). Older MigSchema / attribute-based workflows are not supported.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

Version Downloads Last Updated
11.2.0 42 8/4/2026
11.1.0 58 8/3/2026
11.0.0 56 7/31/2026
10.0.0 83 7/30/2026
9.1.0 133 6/2/2026
9.0.0 131 6/1/2026
8.3.0 114 5/29/2026
8.2.0 115 5/29/2026
8.1.1 127 5/28/2026
8.1.0 145 5/28/2026
8.0.4 131 5/26/2026
8.0.3 131 5/26/2026
8.0.2 137 5/24/2026
8.0.1 135 5/23/2026
8.0.0 131 5/17/2026
7.0.2 146 4/14/2026
7.0.1 128 4/14/2026
7.0.0 147 4/11/2026
6.0.1 143 4/10/2026
6.0.0 128 4/10/2026
Loading failed