Skip to content

Quick Start

This guide takes you from zero to a seeded database. If you already have migrations applied and a connection string handy, you’re about 60 seconds away.

  • Node.js 18 or newer (node -v to check)
  • An existing database with your schema already applied. Seedforge reads your tables — it does not create them. Run your migrations first (prisma migrate dev, drizzle-kit push, rails db:migrate, whatever you use).
  • A connection string for PostgreSQL, MySQL, or SQLite — or an ORM schema file if you want SQL output without a live database.

Pick whichever fits your workflow.

Terminal window
# Global install — one-off usage from any shell
npm install -g @otg-dev/seedforge
# Project dev dependency — reproducible in CI
npm install --save-dev @otg-dev/seedforge
# No install — just run it
npx @otg-dev/seedforge --db postgres://localhost/mydb

Point Seedforge at a database and pass --count to choose rows per table:

Terminal window
seedforge --db postgres://localhost/myapp --count 50

Expected output:

seedforge v2.4.0
Introspected 8 tables, 2 enums, 12 foreign keys
Insert order: countries -> users -> categories -> products -> orders -> order_items -> reviews -> audit_log
Generated 400 rows across 8 tables
Seeding complete:
Tables: 8
Rows: 400
Time: 142ms
Mode: DIRECT

Query any table and you’ll see realistic data instead of user_1, user_2:

SELECT first_name, last_name, email FROM users LIMIT 3;
first_name | last_name | email
------------+-----------+----------------------------
Marcus | Chen | marcus.chen@example.com
Fatima | Okafor | fatima.okafor@example.com
Lena | Johansson | lena.johansson@example.com

All generated emails use RFC 2606 reserved domains (@example.com) so no stray test mail ever lands on a real inbox.

Pass --seed <number> to get identical output every run. Same seed, same rows, every time.

Terminal window
seedforge --db postgres://localhost/myapp --count 50 --seed 42

--dry-run runs the full pipeline but skips the final INSERT:

Terminal window
seedforge --db postgres://localhost/myapp --count 50 --dry-run

--output writes a .sql file you can inspect, version, or apply later with psql:

Terminal window
seedforge --db postgres://localhost/myapp --count 50 --output seed.sql
psql $DATABASE_URL < seed.sql

You don’t need a running database at all if you just want SQL out. Prisma, Drizzle, TypeORM, and JPA schemas all work with --output:

Terminal window
seedforge --prisma ./prisma/schema.prisma --count 100 --output seed.sql
Terminal window
seedforge --drizzle ./src/db/schema.ts --output seed.sql
seedforge --typeorm ./src/entities/ --output seed.sql
seedforge --jpa ./src/main/java/com/example/entities/ --output seed.sql

withSeed() is the test-friendly entry point. It lazily connects, wraps everything in a transaction, and rolls back on teardown so tests never pollute each other.

import { withSeed } from '@otg-dev/seedforge'
import { describe, it, afterAll, expect } from 'vitest'
describe('user API', () => {
const { seed, teardown } = withSeed(process.env.TEST_DATABASE_URL!, {
seed: 42,
transaction: true,
})
afterAll(teardown)
it('lists users', async () => {
const users = await seed('users', 10)
const res = await fetch('/api/users')
expect(await res.json()).toHaveLength(10)
})
})

Seedforge inspects connection strings for production-like hostnames — RDS, Cloud SQL, Supabase, Neon, PlanetScale, and friends — and refuses to run unless you confirm. Pass --yes to skip the prompt in automation.

Terminal window
# CI against an ephemeral preview DB
seedforge --db $PREVIEW_DATABASE_URL --count 50 --seed 42 --quiet --yes
  • CLI reference — every flag, with examples
  • Schema sources — PG, MySQL, SQLite, Prisma, Drizzle, TypeORM, JPA
  • Examples — recipes for CI, test suites, large datasets, and weighted enums