npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@tej_gokani/sqlsmith

v0.1.0

Published

SQLSmith converts JavaScript object schemas into clean, safe, Supabase-ready Postgres SQL migration files with schema diffing, CLI tools, and type overrides.

Downloads

6

Readme

SQLSmith

JavaScript Schema to Postgres (Supabase) Migration Generator

SQLSmith converts JavaScript object schemas into clean, safe, Supabase-ready Postgres SQL migration files with schema diffing, CLI tools, and type overrides.

🚀 Features

  • JS → SQL Schema Generation - Write schemas in JavaScript, get clean SQL
  • 🔄 Schema Diffing - Generate ALTER statements from schema changes
  • 📦 Supabase-Ready - Timestamped migrations in the Supabase format
  • 🎯 Shorthand Notation - Concise column definitions ("uuid:pk", "text:unique:notnull")
  • 🔐 RLS Policy Templates - Optional Supabase Row Level Security policy generation
  • ⚙️ Highly Configurable - Type overrides, naming strategies, timestamps, and more
  • 🧪 Well-Tested - Comprehensive test suite included
  • 🛠️ CLI + Programmatic API - Use from command line or Node.js code

📦 Installation

npm install -D sqlsmith
# or
yarn add -D sqlsmith

🏁 Quick Start

1. Initialize SQLSmith

npx sqlsmith init

This creates:

  • sqlsmith.config.js - Configuration file
  • schema.example.js - Example schema file

2. Define Your Schema

Edit schema.example.js:

export default {
  users: {
    id: "uuid:pk",
    name: "text:notnull",
    email: "text:unique:notnull",
    age: "integer:default=18",
    profile: {
      bio: "text",
      avatar_url: "text"
    },
    created_at: "timestamptz:default=now()"
  },
  profiles: {
    id: "uuid:pk",
    user_id: "uuid:fk=users.id",
    visibility: "text:default='public'"
  }
};

3. Generate SQL

# Generate SQL file
npx sqlsmith generate --schema=schema.example.js --out=schema.sql

# Or create a timestamped migration
npx sqlsmith migrate --schema=schema.example.js --message="init"

4. Output

Generated SQL:

CREATE TABLE IF NOT EXISTS public.users (
  id uuid PRIMARY KEY,
  name text NOT NULL,
  email text UNIQUE NOT NULL,
  age integer DEFAULT 18,
  profile jsonb,
  created_at timestamptz DEFAULT now()
);

CREATE TABLE IF NOT EXISTS public.profiles (
  id uuid PRIMARY KEY,
  user_id uuid REFERENCES public.users(id),
  visibility text DEFAULT 'public'
);

📚 CLI Commands

init

Create configuration and example schema files

npx sqlsmith init

generate

Generate SQL from schema

npx sqlsmith generate --schema=schema.js --out=schema.sql

migrate

Create timestamped migration file

npx sqlsmith migrate --schema=schema.js --message="create users table"

diff

Generate ALTER statements from schema differences

npx sqlsmith diff --from=old-schema.js --to=new-schema.js --out=diff.sql

policies

Generate Supabase RLS policy templates

npx sqlsmith policies --table=users --out=policies.sql

💻 Programmatic API

import { generateSQL, diffSchemas, migrate } from "sqlsmith";

// Generate SQL from schema
const sql = generateSQL(schemaObject);

// Generate ALTER statements
const diff = diffSchemas(oldSchema, newSchema);

// Create migration file
const filePath = migrate(schemaObject, "./supabase/migrations", "init");

📝 Schema Notation

Shorthand Format

Column definitions use the format: "<type>[:modifier1][:modifier2]..."

{
  id: "uuid:pk",                           // Primary key
  email: "text:unique:notnull",            // Unique and NOT NULL
  age: "integer:default=18",               // Default value
  created_at: "timestamptz:default=now()", // Function default
  user_id: "uuid:fk=users.id",            // Foreign key
  settings: "jsonb:default='{}'"          // JSON default
}

Supported Modifiers

  • pk - Primary key (implies NOT NULL)
  • notnull - NOT NULL constraint
  • unique - UNIQUE constraint
  • default=<value> - Default value
  • fk=<table>.<column> - Foreign key reference

Type Mapping

JavaScript types to PostgreSQL:

string   → text
number   → integer
boolean  → boolean
uuid     → uuid
object   → jsonb
array    → jsonb

Explicit PostgreSQL types supported:

  • text, varchar, integer, bigint, smallint
  • numeric, decimal, real, double precision
  • uuid, boolean, date, timestamp, timestamptz
  • json, jsonb, text[], integer[], etc.

Nested Objects

Nested objects are automatically converted to jsonb:

{
  users: {
    profile: {
      bio: "text",
      avatar_url: "text"
    }
  }
}

Becomes:

profile jsonb

⚙️ Configuration

sqlsmith.config.js:

export default {
  schema: 'public',              // PostgreSQL schema
  namingStrategy: 'snake_case',  // snake_case or camelCase
  timestamps: true,              // Add created_at/updated_at
  jsonForObjects: true,          // Convert nested objects to jsonb
  foreignKeyStrategy: 'inline',  // inline or separateTable
  policyGeneration: false,       // Generate RLS policies
  supabaseDir: './supabase/migrations',
  typeOverrides: {
    // Custom type mappings
    id: 'uuid',
    email: 'varchar(255)'
  }
};

Options

| Option | Type | Default | Description | |--------|------|---------|-------------| | schema | string | 'public' | PostgreSQL schema name | | namingStrategy | string | 'snake_case' | Naming convention | | timestamps | boolean/object | false | Auto-add timestamps | | jsonForObjects | boolean | true | Convert objects to jsonb | | foreignKeyStrategy | string | 'inline' | FK strategy | | policyGeneration | boolean | false | Generate RLS policies | | supabaseDir | string | './supabase/migrations' | Migration directory | | typeOverrides | object | {} | Custom type mappings |

🔄 Schema Diffing

SQLSmith can generate ALTER statements by comparing two schemas:

// old-schema.js
export default {
  users: {
    id: "uuid:pk",
    name: "text"
  }
};

// new-schema.js
export default {
  users: {
    id: "uuid:pk",
    name: "text",
    email: "text:unique:notnull"  // Added column
  }
};
npx sqlsmith diff --from=old-schema.js --to=new-schema.js

Output:

ALTER TABLE public.users ADD COLUMN email text UNIQUE NOT NULL;

Destructive Changes

SQLSmith warns about destructive changes:

-- WARNING: DROP_COLUMN on users.name is DESTRUCTIVE!
-- ALTER TABLE public.users DROP COLUMN name;

🔐 Supabase Integration

Migrations

SQLSmith generates timestamped migration files compatible with Supabase:

supabase/migrations/
  20251121143022_create_users.sql
  20251121143045_add_profiles.sql

RLS Policies

Generate Row Level Security policy templates:

npx sqlsmith policies --table=users

Output:

-- Enable Row Level Security
ALTER TABLE public.users ENABLE ROW LEVEL SECURITY;

-- Policy: Authenticated users can view all records
CREATE POLICY "authenticated_select_policy" ON public.users
  FOR SELECT
  TO authenticated
  USING (true);

-- Policy: Users can update their own records
CREATE POLICY "user_update_own_policy" ON public.users
  FOR UPDATE
  TO authenticated
  USING (auth.uid() = user_id)
  WITH CHECK (auth.uid() = user_id);

🧪 Testing

Run the test suite:

npm test

Tests include:

  • Parser validation
  • SQL generation
  • Schema diffing
  • Type mapping
  • Configuration handling

📁 Project Structure

sqlsmith/
├── bin/
│   └── sqlsmith.js           # CLI entry point
├── src/
│   ├── index.js              # Main API
│   ├── cli.js                # CLI commands
│   ├── parser/
│   │   ├── parseSchema.js    # Schema parser
│   │   └── validateSchema.js # Schema validator
│   ├── generator/
│   │   ├── sqlCreate.js      # CREATE TABLE generator
│   │   ├── sqlAlter.js       # ALTER TABLE generator
│   │   └── typeMapper.js     # Type mapping
│   ├── integrator/
│   │   ├── supabaseWriter.js # Migration file writer
│   │   └── policyGenerator.js# RLS policy generator
│   └── utils/
│       ├── fileWriter.js     # File utilities
│       ├── logger.js         # Logger
│       └── timestamp.js      # Timestamp generator
├── templates/
│   ├── migration.sql.tpl     # Migration template
│   └── policy.template.sql   # Policy template
├── examples/
│   └── schema.example.js     # Example schema
├── tests/
│   ├── parser.test.js        # Parser tests
│   └── generator.test.js     # Generator tests
└── package.json

🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

📄 License

MIT © Your Name

🔗 Links

✨ Examples

Basic Schema

export default {
  posts: {
    id: "uuid:pk",
    title: "text:notnull",
    content: "text",
    author_id: "uuid:fk=users.id",
    published: "boolean:default=false",
    created_at: "timestamptz:default=now()"
  }
};

With Timestamps Config

// sqlsmith.config.js
export default {
  timestamps: {
    created_at: true,
    updated_at: true
  }
};

// schema.js
export default {
  articles: {
    id: "uuid:pk",
    title: "text:notnull"
    // created_at and updated_at added automatically
  }
};

Complex Schema

export default {
  organizations: {
    id: "uuid:pk",
    name: "text:notnull",
    settings: "jsonb:default='{}'",
    created_at: "timestamptz:default=now()"
  },
  users: {
    id: "uuid:pk",
    email: "text:unique:notnull",
    org_id: "uuid:fk=organizations.id",
    role: "text:default='member'",
    metadata: {
      bio: "text",
      avatar: "text",
      preferences: {}
    }
  },
  posts: {
    id: "uuid:pk",
    author_id: "uuid:fk=users.id",
    org_id: "uuid:fk=organizations.id",
    title: "text:notnull",
    content: "text",
    tags: "text[]",
    published_at: "timestamptz"
  }
};

Built with ❤️ for the Supabase and PostgreSQL community