# Let's start

<Steps>

<Step>
### Install

`okmodel` has no runtime dependencies. Each driver is an optional peer. Pick the one the runtime already has.

<Tabs items={["postgres.js", "node-postgres", "PGlite", "Bun.sql"]}>

<Tab value="postgres.js">

The default on Node and Bun. It connects to a Postgres server.

```sh title="postgres.js"
bun add okmodel postgres
```

```ts title="db.ts"
import { connect } from "okmodel/pg/postgresjs";
```

</Tab>

<Tab value="node-postgres">

The other server driver on Node and Bun, when `pg` is already installed. `pg` ships no types, so `@types/pg` is a dev dependency.

```sh title="node-postgres"
bun add okmodel pg
bun add -D @types/pg
```

```ts title="db.ts"
import { connect } from "okmodel/pg/pg";
```

</Tab>

<Tab value="PGlite">

Postgres runs in the process, on Node or Bun. There is no server to start. The connect target is a data directory, or omit it for memory.

```sh title="PGlite"
bun add okmodel @electric-sql/pglite
```

```ts title="db.ts"
import { connect } from "okmodel/pg/pglite";
```

</Tab>

<Tab value="Bun.sql">

Built into Bun. No extra package. This entry does not run on Node. `bunx okm` still uses Node. `bun --bun okm` is the Bun runtime.

```sh title="Bun.sql"
bun add okmodel
```

```ts title="db.ts"
import { connect } from "okmodel/pg/bun";
```

</Tab>

</Tabs>

</Step>

<Step>
### Define the table

`table()` stores the columns. `t.identity().primaryKey()` makes `id` the primary key.

```ts title="schema.ts"
import { table, t } from "okmodel/pg";

export const notes = table("notes", {
  id: t.identity().primaryKey(),
  title: t.text(),
});
```

`t.identity()` is a `bigint`, generated always. Insert omits `id`. The default codec is a string. A key of more than one column is the `primaryKey` option. [Keys](/docs/define/table/keys).

</Step>

<Step>
### Define the schema

`schema()` compiles the tables into one catalog. The module default-exports that result.

```ts title="schema.ts"
import { schema, table, t } from "okmodel/pg";

export const notes = table("notes", {
  id: t.identity().primaryKey(),
  title: t.text(),
});

export default schema({ tables: [notes] }); // [!code focus]
```

</Step>

<Step>
### Define the config

Point `schema` at the file from the previous step. `database` is the URL push connects to.

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

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

`okm push` loads `okmodel.config.ts` from the project directory. The file default-exports `defineConfig`. A file that does not is refused. A module that is not a `schema()` is refused: `<path> must export a schema().` Other options are on [Config](/docs/define/config).

</Step>

<Step>
### Push

`okm push` connects and creates the tables. It does not write a SQL file.

```sh
bunx okm push
```

A protected target refuses push (OKM1850). No schema change prints `no changes`. `bunx okm` runs with Node. `bun --bun okm` uses the Bun runtime.

</Step>

<Step>
### Connect

`connect` takes the direct URL and the schema. The process keeps `db`. Direct asserts the URL. Safe refuses an empty `DATABASE_URL`. The options are on [Connect](/docs/define/connect).

<Tabs items={["Direct", "Safe"]}>

<Tab value="Direct">

```ts title="db.ts"
import { connect } from "okmodel/pg/postgresjs";

import schema from "./schema.ts";

export const db = connect(process.env.DATABASE_URL!, { schema }); // [!code focus]
```

</Tab>

<Tab value="Safe">

```ts title="db.ts"
import { connect } from "okmodel/pg/postgresjs";

import schema from "./schema.ts";

const url = process.env.DATABASE_URL;
if (url === undefined || url.length === 0) throw new Error("DATABASE_URL is not set"); // [!code focus]

export const db = connect(url, { schema });
```

</Tab>

</Tabs>

</Step>

<Step>
### 🎉 That's it!

That's it! You're now ready to use okmodel in your application. Continue to [Basic Usage](/docs/start/basic-usage) to learn how to insert, find, update, and delete.
</Step>

</Steps>
