Database Seeding CLI with Schema-Aware Fake Data
A command-line tool that reads your database schema and generates realistic, referentially-consistent fake data for local development and testing. Instead of hand-written seed scripts that rot as schemas change, this CLI introspects the live schema, plans a valid insertion order across foreign keys, and produces deterministic, reproducible datasets.
Who Is This For?
- Backend developers who need realistic local data without writing seed scripts by hand
- Junior developers learning how databases, foreign keys, and migrations fit together
- Open-source contributors who want to add seed data to a project without guessing at its schema
- Students building database-backed applications and tired of inserting rows manually
- QA engineers who need controlled, repeatable test datasets with known values
The Problem
Every developer who has built a database-backed application has hit the same wall: you need data to develop against, but the data has to look real, respect your schema, and change when your schema changes.
The usual approaches all have drawbacks:
- Hand-written seed scripts start out fine, then silently break when a migration adds a required column or renames a table. Nobody enjoys updating 400 lines of INSERT statements.
- Generic faker libraries generate plausible-looking values, but they have no idea about your schema. They happily produce a
user_id that references a row that doesn’t exist, violating your foreign keys and crashing your queries. - Copying production data is fast but dangerous — it exposes real user data in development environments, often in violation of privacy policies, and bloats your local database.
The core problem: seeding tools are either too manual (scripts you maintain) or too blind (libraries that ignore your schema). There is a gap between them — a tool that reads the schema and generates data that actually fits it.
How It Works
The CLI works in three stages: introspect, plan, and generate.
1. Schema Introspection
The tool connects to your database (SQLite and PostgreSQL in the first version) and reads the live schema — tables, columns, types, nullability, defaults, primary keys, and foreign keys. It never guesses: it builds a model of your actual schema, so the generated data matches the constraints you’ve already defined.
2. Generation Planning
Once it knows the schema, the tool plans the generation:
- Foreign-key graph traversal — tables are ordered so that referenced rows are created before referencing rows. If
orders references customers, customers are seeded first. - Per-column formatters — each column type maps to an appropriate fake-data formatter (names for text columns, realistic prices for decimals, valid UUIDs for UUID columns, future dates for
expires_at). - Deterministic seeding — a fixed seed value produces the exact same dataset every time, so tests are reproducible and teammates see identical data.
3. Generation
The tool writes rows in the planned order, respecting foreign keys and column constraints. The result is a database that looks like real data, not a dump of random strings.
┌─────────────┐ ┌──────────────┐ ┌──────────────────┐ │ Database │────▶│ Schema │────▶│ FK-Aware │ │ (SQLite / │ │ Introspector│ │ Generation │ │ Postgres) │ └──────────────┘ │ Engine │ └─────────────┘ └────────┬─────────┘ │ ┌────────────▼─────────┐ │ Deterministic, │ │ referentially-valid │ │ rows in your DB │ └──────────────────────┘
Core Workflow
db-seed init → create a seed config file for your project db-seed plan → print the generation order and row counts without touching the DB db-seed run → generate and insert the data db-seed run --seed 42 → same dataset every time (reproducible)
Init — connect, introspect the schema, and write a starter config.Configure — optionally override formatters per column or add custom rules.Plan — review what will be generated before anything is written.Run — generate deterministic, FK-consistent data.Key Features
- Schema-aware generation — reads your actual schema; nothing is guessed
- Foreign-key ordering — referential integrity preserved automatically
- Per-column formatter library — sensible defaults for common column types, with custom overrides
- Deterministic seeds — the same seed always produces the same data
- Dry-run planning —
db-seed plan shows what will happen before it happens - Config as code — seed configuration lives in the repo, reviewable in pull requests
- TypeScript types and docs — a friendly developer experience for contributors
Functional Requirements
Connect to a SQLite file or PostgreSQL database and read its schema.Build a table/column/constraint model from the introspection result.Topologically sort tables by foreign-key dependencies.Map column types to default formatters (text, integer, decimal, boolean, date, UUID, email, name).Support per-column and per-table formatter overrides via config.Honor not-null, unique, default, and foreign-key constraints.Accept a seed value for deterministic output.Provide init, plan, and run subcommands with clear output.Exit with a non-zero code and a readable message on constraint failures.User Stories
- As a backend developer, I want to regenerate realistic local data after a migration, so that my development environment matches my schema.
- As a QA engineer, I want deterministic seed data, so that test runs are reproducible and failures are not caused by random input.
- As a junior developer, I want to understand the generation order, so that I can learn how foreign keys work without reading an ORM manual.
MVP Scope
SQLite connector with full introspection (tables, columns, FKs).FK-ordered generation for a flat set of tables.Default formatters for the most common column types.Deterministic seeding via a --seed flag.init, plan, and run subcommands.A JSON config file with per-column overrides.PostgreSQL support, custom formatter plugins, unique-value tracking, and interactive prompts are natural second-phase additions.
Project Timeline
- Phase 1 — Research (Week 1): Study existing tools (Faker, seed libraries, ORM seeders) and map the introspection APIs for SQLite.
- Phase 2 — MVP (Weeks 2–4): Schema introspection, FK graph traversal, deterministic generation,
init/plan/run. - Phase 3 — Testing (Week 5): Golden-fixture tests, constraint-failure tests, manual testing against sample schemas.
- Phase 4 — Deployment (Week 6): Package as an npm CLI, publish docs, add CI with a matrix of Node versions.
- Phase 5 — Improvements (Ongoing): PostgreSQL connector, custom formatters, unique constraints, teams’ real-world feedback.
Testing Strategy
- Golden fixtures — fixed seed + fixed schema must produce byte-identical output; commit the expected output.
- Constraint tests — generated rows must pass every schema constraint (not-null, unique, FK) against a fresh database.
- Idempotency tests — running with the same seed twice yields the same rows.
- Negative tests — a config with an impossible constraint fails with a clear error rather than corrupting data.
- Manual smoke test — seed a realistic multi-table schema and run a few queries against it.
Deployment Considerations
- Package with
npm pack and publish as a public package. - Pin Node.js engines; test against a support matrix in CI.
- Keep the tool zero-config for the common case:
npx db-seed init should work out of the box. - Document usage with a README, examples, and a short “why” section explaining the design.
Security Considerations
- Never point the tool at production. Generated data must only ever be written to development, test, or staging databases. The
init command should warn loudly if the target looks like a production connection. - Credentials are read from environment variables or a
.env file, never stored in config. - The tool does not upload or transmit any data — everything runs locally.
Success Metrics
- Time to get a new contributor from clone to a working local database.
- Percentage of seed runs that complete without constraint failures.
- Reproducibility: identical seed + schema always yields identical rows.
- Adoption signals: downloads, stars, and contributors for an open-source project.
Common Challenges
- Constraint ordering — unique columns and cross-table cycles need careful handling (cycles can be broken by deferrable constraints or inserting a placeholder and updating).
- Type mapping — every database has quirky types (arrays, enums, JSON columns) that need sensible defaults.
- Performance — generating tens of thousands of rows efficiently requires batching inserts rather than one-by-one execution.
- Config drift — when the config no longer matches the schema, the tool must say so clearly instead of guessing.
Learning Objectives
- Understand database schemas: tables, columns, constraints, and foreign keys.
- Practice graph traversal (topological ordering) in a real application.
- Learn CLI design: subcommands, flags, exit codes, and good error messages.
- Practice deterministic testing and golden-file test patterns.
Why This Idea Is Different
Generic faker libraries generate values in a vacuum — they produce a string called “name” without knowing your schema or your relationships. This CLI is schema-aware: it introspects the database, plans a valid insertion order, and guarantees referential consistency. That makes it the data-generation counterpart to API mocking: just as an API mocking CLI gives developers a realistic API to develop against, this tool gives them a realistic database.
It is deliberately a CLI rather than a framework — it works with whatever schema exists today, without changing how your application is built.
| Tool | Approach | Limitation |
|——|———-|————|
| Faker libraries | Generate random values per field | Unaware of schema and foreign keys |
| ORM seeders | Seed via the ORM’s model layer | Tied to one ORM; can drift from raw SQL schema |
| Factory libraries | Define row factories in code | Manual maintenance as schema changes |
| Dump/copy tools | Copy real data | Privacy risk; heavy; not deterministic |
This Idea fills the gap: schema introspection plus deterministic, referentially-consistent generation, as a standalone CLI.
Technology Stack
- Node.js 18+ — runtime; broad developer familiarity
- TypeScript — type-safe codebase with generated type declarations
- better-sqlite3 — fast, synchronous SQLite access for introspection and writing
- commander — CLI argument parsing
- faker — underlying value generation for formatters (a library, not a standard)
- vitest — testing with golden fixtures
Future Enhancements
- PostgreSQL connector with full introspection support
- Custom formatter plugins so teams can plug in domain-specific generators
- Unique-constraint tracking for columns that must not repeat
- Interactive mode with prompts for quick, throwaway datasets
- Docker Compose helper to seed a fresh database in one command
- Diff-aware regeneration that only touches rows affected by schema changes
Browse more Open Source ideas · Innovation Ideas