npm package: @getprofixel/supabase-typegen-fast
Description: Fast Supabase TypeScript type generation. Direct Postgres connection — no CLI dependency, no hanging, 2 seconds.
Latest version: 1.0.0

# supabase-type-gen

**Fast Supabase TypeScript type generation. Direct Postgres connection — no CLI dependency, no hanging, 2 seconds.**

Drop-in replacement for `supabase gen types typescript` that actually works.

---

## Why?

The official `supabase gen types typescript` command uses the Supabase Management API, which:

- **Hangs indefinitely** on many projects (20+ minutes with no output)
- **Times out** on larger schemas
- **Can't be killed gracefully** — you Ctrl+C and pray
- **Has no progress indicator** — you never know if it's working or stuck

`supabase-type-gen` connects **directly to your Postgres database**, introspects the schema, and writes the types file. It completes in **~2 seconds** regardless of schema size.

```
# Before: ☠️
npx supabase gen types typescript --project-id abc123 > types.ts
# ... 20 minutes later, still waiting ...

# After: ⚡
npx supabase-type-gen --db-url "$SUPABASE_DB_URL" --output types.ts
# ✓ Types written to types.ts (847 lines, 1823ms)
```

## Quick Start

### npx (no install)

```bash
npx supabase-type-gen --db-url "postgresql://postgres.xxx:password@aws-0-region.pooler.supabase.com:5432/postgres" --output ./lib/supabase/database.types.ts
```

### Install globally

```bash
npm install -g supabase-type-gen
supabase-type-gen --db-url "$SUPABASE_DB_URL" --output ./database.types.ts
```

### Install as dev dependency

```bash
npm install -D supabase-type-gen
```

Add to `package.json`:

```json
{
  "scripts": {
    "types:supabase": "supabase-type-gen --db-url \"$SUPABASE_DB_URL\" --output ./lib/supabase/database.types.ts"
  }
}
```

```bash
npm run types:supabase
```

## Getting Your Connection String

1. Go to your [Supabase Dashboard](https://supabase.com/dashboard)
2. Navigate to **Settings → Database → Connection string**
3. Select **URI** format
4. Copy the **Session mode** connection string (port `5432`)
5. Replace `[YOUR-PASSWORD]` with your database password

The connection string looks like:

```
postgresql://postgres.xxxxxxxxxxxx:YOUR_PASSWORD@aws-0-us-east-1.pooler.supabase.com:5432/postgres
```

> **Tip:** Use the direct connection or session pooler (port `5432`), not the transaction pooler (port `6543`). The type generator needs to run schema introspection queries that require a direct session.

## Usage

### CLI Options

```
supabase-type-gen --db-url <connection_string> [options]

OPTIONS
  --db-url <url>          Postgres connection string (required)
                          Also reads from SUPABASE_DB_URL or DATABASE_URL env vars
  --output <path>         Output file path (default: ./database.types.ts)
  --schema <name>         Postgres schema to introspect (default: public)
  --check                 Don't write — exit 1 if types would change (for CI)
  --connection-timeout    Connection timeout in ms (default: 10000)
  --query-timeout         Query timeout in ms (default: 30000)
  --help, -h              Show help
  --version, -v           Show version
```

### Environment Variables

Instead of passing `--db-url` every time, set an environment variable:

```bash
# .env.local (don't commit this)
SUPABASE_DB_URL="postgresql://postgres.xxx:password@host:5432/postgres"
```

The CLI checks in order: `--db-url` flag → `SUPABASE_DB_URL` env → `DATABASE_URL` env.

### CI Check Mode

Run in CI to ensure types are committed and up to date:

```bash
supabase-type-gen --db-url "$SUPABASE_DB_URL" --output ./types.ts --check
```

- Exit `0`: types are current
- Exit `1`: types are stale — run without `--check` to regenerate

### Custom Schema

```bash
supabase-type-gen --db-url "$DATABASE_URL" --schema my_schema --output ./types.ts
```

## Programmatic API

Use it in your own scripts or tooling:

```typescript
import { generate } from "supabase-type-gen";

const content = await generate({
  dbUrl: process.env.SUPABASE_DB_URL!,
  output: "./lib/supabase/database.types.ts",
  schema: "public",
  check: false,
  connectionTimeout: 10000,
  queryTimeout: 30000,
});

console.log(`Generated ${content.split("\n").length} lines`);
```

### Lower-level API

```typescript
import { introspectSchema, generateTypesFile } from "supabase-type-gen";

// Step 1: Introspect
const schema = await introspectSchema(
  process.env.SUPABASE_DB_URL!,
  "public",
  10000,
  30000
);

console.log(`Found ${schema.tables.length} tables`);
console.log(`Found ${Object.keys(schema.enums).length} enums`);

// Step 2: Generate
const content = generateTypesFile(schema, "public");
```

## Output Format

The generated file is **identical in structure** to the official Supabase CLI output. It's a drop-in replacement — no code changes needed.

```typescript
export type Json = string | number | boolean | null | { [key: string]: Json | undefined } | Json[];

export type Database = {
  public: {
    Tables: {
      users: {
        Row: {
          id: string;
          email: string;
          created_at: string;
        };
        Insert: {
          id?: string;
          email: string;
          created_at?: string;
        };
        Update: {
          id?: string;
          email?: string;
          created_at?: string;
        };
        Relationships: [
          {
            foreignKeyName: "users_org_id_fkey";
            columns: ["org_id"];
            isOneToOne: false;
            referencedRelation: "organizations";
            referencedColumns: ["id"];
          },
        ];
      };
      // ... more tables
    };
    Views: { /* ... */ };
    Functions: { /* ... with typed args and returns */ };
    Enums: { /* ... */ };
    CompositeTypes: { /* ... */ };
  };
};

// Plus: Tables<>, TablesInsert<>, TablesUpdate<>, Enums<> helper types
```

### What's Included

| Feature | Supported |
|---------|-----------|
| Tables (Row, Insert, Update) | ✅ |
| Views | ✅ |
| Enums | ✅ |
| Foreign key relationships | ✅ |
| Function args and return types | ✅ |
| Set-returning functions | ✅ |
| Array columns | ✅ |
| Nullable columns | ✅ |
| Default/identity detection for Insert | ✅ |
| Helper types (Tables, TablesInsert, etc.) | ✅ |
| Composite types | ⬜ (empty, same as official CLI) |
| Multiple schemas | ✅ (via `--schema`) |

## Comparison

| | `supabase gen types` | `supabase-type-gen` |
|---|---|---|
| **Speed** | 20+ minutes (often hangs) | ~2 seconds |
| **Connection** | Management API (HTTP) | Direct Postgres (TCP) |
| **Dependencies** | Supabase CLI (~200MB) | `pg` only (~2MB) |
| **Timeout handling** | None (hangs forever) | Configurable (10s/30s defaults) |
| **CI mode** | ❌ | ✅ `--check` flag |
| **Custom schema** | ✅ | ✅ |
| **Programmatic API** | ❌ | ✅ |
| **Error messages** | Generic | Specific (auth, timeout, connection) |
| **Output format** | ✅ Official | ✅ Identical |

## Postgres Type Mapping

| Postgres Type | TypeScript Type |
|---|---|
| `int2`, `int4`, `int8`, `float4`, `float8`, `numeric` | `number` |
| `text`, `varchar`, `char`, `uuid`, `citext` | `string` |
| `bool` | `boolean` |
| `json`, `jsonb` | `Json` |
| `timestamp`, `timestamptz`, `date`, `time` | `string` |
| `bytea`, `inet`, `cidr`, `macaddr` | `string` |
| `tsvector`, `tsquery` | `string` |
| `point`, `line`, `polygon`, `circle` | `string` |
| `int4range`, `tstzrange`, `daterange` | `string` |
| `money`, `xml`, `interval` | `string` |
| `ARRAY` types | `<element_type>[]` |
| User-defined enums | `Database["public"]["Enums"]["enum_name"]` |
| `void` | `undefined` |
| `record` | `Record<string, unknown>` |
| Unknown | `unknown` |

## Troubleshooting

### Connection refused

```
Could not connect to the database. Check your connection string.
```

- Verify the connection string is correct
- Make sure you're using port `5432` (not `6543`)
- Check if your IP is allowed in Supabase Network Restrictions (Dashboard → Settings → Network)

### Authentication failed

```
Authentication failed. Check your database password.
```

- The password in the connection string may be wrong
- Reset it in Dashboard → Settings → Database → Database Password

### Connection timed out

```
Connection timed out.
```

- Your network may be blocking outbound Postgres connections
- Try increasing `--connection-timeout 30000`
- Some corporate firewalls block port 5432 — try from a different network

### Types don't match the official CLI output exactly

The structure is identical, but there may be minor differences:

- All identifiers are always quoted (e.g., `"id"` instead of `id`)
- Function overloads may be handled differently
- The official CLI may include internal Supabase functions; this tool only includes functions in your specified schema

## Works With

- **Supabase JS Client** (`@supabase/supabase-js`) — pass the `Database` type as a generic
- **Any Postgres database** — not limited to Supabase, works with any Postgres instance
- **Neon, Railway, RDS, etc.** — any Postgres host that accepts direct connections

## Contributing

Contributions welcome! Please open an issue first to discuss what you'd like to change.

```bash
git clone https://github.com/getprofixel/supabase-type-gen.git
cd supabase-type-gen
npm install
npm run build
```

To test locally against your database:

```bash
node dist/cli.js --db-url "$SUPABASE_DB_URL" --output ./test-output.ts
```

## License

[MIT](LICENSE)