You know that thing where you have a project idea at 1am, you're hyped, and then you spend the next 2 hours setting up Postgres, writing migrations, configuring connection strings, and by the time you're done your motivation is gone and you go to bed?
Yeah. That kept happening to me. So I built something about it.
What is SeedORM?
SeedORM is a Node.js ORM that stores everything in local JSON files. No database server, no Docker, no connection strings. You define your models and start building immediately.
Then when your project is ready for the real world, you migrate to Postgres with one command. Same models, same queries, same API. Nothing changes except where the data lives.
npm install seedorm
The Problem
Every side project I start follows the same pattern:
- Cool idea hits me
- Create new folder,
npm init - Okay now I need a database
- Do I use Postgres? MongoDB? SQLite?
- Spend 30 minutes setting up Docker, env vars, connection pooling
- Write migration files
- I'm tired now
- Abandon project
I wanted something where step 3 is just... skip.
How It Works
Define your models like you normally would:
import { SeedORM, FieldType } from "seedorm";
const db = new SeedORM();
await db.connect();
const User = db.model({
name: "users",
fields: {
name: { type: FieldType.String, required: true },
email: { type: FieldType.String, unique: true },
age: { type: FieldType.Number },
},
});
await User.init();
That's it. No database running. No config file pointing to localhost:5432. It just writes to JSON files in a data/ folder.
Now use it like any ORM:
// Create
const user = await User.create({ name: "Josh", email: "josh@hey.com", age: 24 });
// Query
const adults = await User.find({ filter: { age: { $gte: 18 } } });
// Update
await User.update(user.id, { age: 25 });
// Delete
await User.delete(user.id);
Relations
It supports the relation types you'd expect:
const Post = db.model({
name: "posts",
fields: {
title: { type: FieldType.String, required: true },
body: { type: FieldType.String },
},
relations: {
author: {
type: "belongsTo",
model: "users",
foreignKey: "authorId",
},
},
});
hasMany, belongsTo, manyToMany. They all work the same way when you eventually switch to Postgres.
The Studio
I got tired of opening JSON files to check my data, so I built a visual browser for it. Run seedorm studio and you get a web UI at localhost:4200 where you can browse collections, search across fields, paginate through documents, and edit records.
It's nothing fancy. It's just nice to have when you're building and want to see what's in your database without writing a query.
Per-Collection File Storage
One thing that bugged me early on was that everything was stored in a single seedorm.json file. With a few thousand documents across multiple collections, that file gets massive.
So now each collection gets its own file:
data/
users.json
posts.json
comments.json
Each file is minified (single line), writes only happen for collections that changed, and if you have an old seedorm.json from a previous version it auto-migrates on startup. You don't have to do anything.
When You're Ready for Postgres
Your project took off. Congrats. Time for a real database.
seedorm migrate to postgres
Your models stay the same. Your queries stay the same. You just change the adapter config:
const db = new SeedORM({
adapter: {
adapter: "postgres",
url: "postgresql://localhost:5432/myapp",
},
});
That's the whole point. Build fast with JSON, switch when it matters.
What It's NOT
Let me be clear about what SeedORM is not:
- It's not a Prisma replacement for your production app with 10 million users
- It's not meant for high-concurrency workloads
- It's not trying to be the last ORM you'll ever use
It's for prototyping, side projects, hackathons, and that 1am idea that deserves to exist without a 30 minute setup ritual.
Try It
npm install seedorm
If you try it, I'd genuinely love to hear what you think. What's missing? What's annoying? What would make you actually use this?
Thanks for reading.

Top comments (0)