# Migrations

`migrations` is where `okm generate` writes SQL. `okm migrate apply` reads the same directory.

| Value | Result |
| --- | --- |
| omitted | The directory `migrations`. |
| a string | That path, resolved from the project directory. |

### omitted

Leave `migrations` out. Generate writes a file such as `0001_init.sql`, using `\n` as the line ending, and writes `0001_init.catalog.json` beside it. The number is one higher than the highest numeric prefix in the directory, padded to four digits. With no prefix, the file starts at `0001`. An empty plan writes nothing in this directory.

### string

Set `migrations` and generate and apply use that directory.

```ts title="okmodel.config.ts"
import { defineConfig } from "okmodel/migrate";

export default defineConfig({
  schema: "./schema.ts",
  migrations: "migrations", // [!code focus]
});
```

Apply loads every `*.sql` file in name order, together with its `.catalog.json`. A SQL file without that snapshot is refused. For `0001_init.sql` the message is `Migration 0001_init is missing its catalog snapshot.`

`okm migrate check` reads this directory and runs the statements it is given. Run it as a non-superuser. The first migration id it lints is [`lintFrom`](/docs/define/config/lint-from).

A type change that rewrites the table is not one `ALTER COLUMN … TYPE`. It is five migrations: add the new column, backfill it, dual-write, switch reads, then drop the old column. See [type change](/docs/reference/type-change).

### Line endings

`okm generate init` writes `.gitattributes` in the project when that file is missing. An existing file stays as it is.

```text
migrations/*.sql text eol=lf
*.catalog.json text eol=lf
.okm/** text eol=lf
```

The first line is the literal pattern `migrations/*.sql`.

A migration file is read as LF. `\r\n` and a lone `\r` become `\n`, including inside a SQL string. A leading UTF-8 BOM is stripped.

<Callout type="error" title="UTF-16">
A null byte is refused. The message is the file path followed by `is UTF-16. Save the file as UTF-8.`
</Callout>
