neoorm
v0.3.1
Published
TypeScript-first PostgreSQL ORM with schema DSL, codegen, and typed relations
Maintainers
Readme
NeoOrm
PostgreSQL dialect ships today — MySQL, SQLite, and others are on the roadmap.
npm install neoorm pgRequires Node.js 20+ (PostgreSQL driver ships now; more databases coming).
Why NeoOrm?
No any. No codegen runtime. No lock-in.
Most ORMs force you to learn their query language, fight their type system, or ship a heavy runtime. NeoOrm takes a different approach: you write a plain TypeScript schema, it generates a typed client, and you write real SQL — amplified by types, not abstracted away.
- Schema as code — one source of truth for types and the database
- Generated client — zero-cost abstractions, full autocomplete
- Relations done right — nested reads, writes, and filters without N+1 footguns
- PostgreSQL powered — arrays, JSONB, PostGIS, enums, full-text, extensions — no abstraction layer that gets in the way. MySQL, SQLite, and more are coming.
- Migrations built-in — diff your schema, get SQL, deploy. Rollback supported.
Quick start
npx neoorm init # scaffold schema, config, client
npx neoorm migrate deploy # create tablesimport { db } from "./neoorm/client.js";
// Create with nested relation write
const user = await db.users.create({
data: {
email: "[email protected]",
profile: { create: { name: "Alice" } },
},
});
// Fetch with typed includes, pagination, and filters
const posts = await db.posts.findMany({
where: { published: true, tags: { some: { slug: "typescript" } } },
orderBy: { createdAt: "desc" },
take: 20,
with: { author: true, _count: { comments: true } },
});Features
Documentation
| Topic | | |-------|-| | Getting started | Setup, manual config, env vars, tenant schemas | | Schema DSL | Tables, columns, types, enums, indexes, many-to-many, naming strategy | | Queries | CRUD, where clauses, pagination, aggregates, distinct | | Relation writes | Nested connect/create/disconnect/set/delete | | Transactions | Interactive, batch, nested, isolation levels | | Migrations | Deploy, dev, status, rollback, reset | | CLI reference | All commands and flags | | Configuration | Config file options reference | | Plugins | PostGIS, citext, custom plugins |
See the blog example for a complete schema, and queries.example.ts for typed queries and mutations.
API surface
| Import | Purpose |
|--------|---------|
| neoorm | defineConfig, createNeoOrmClient, createNeoOrmClientFromPool, client types |
| neoorm/schema | Schema DSL (defineSchema, table, column builders, fk, manyToMany, index, unique, primaryKey) |
| neoorm/sql | Tagged SQL templates (sql), SQL fragment builder, fluent query builder |
| neoorm/plugins | Plugin registry, NeoOrmPlugin, ColumnTypePlugin |
| neoorm/plugins/postgis | PostGIS column types (geometry, geography, point) and spatial operators |
Philosophy
NeoOrm was built because existing TypeScript ORMs either sacrificed type safety for flexibility, or sacrificed flexibility for type safety. We think you shouldn't have to choose.
- Schema is the source of truth — not decorators, not reflection, not a proprietary DSL. Your schema file is plain TypeScript.
- Generated code is a compile-time artifact — no runtime dependency on the schema. Swap the schema, regenerate, everything still compiles.
- SQL is not hidden — the client compiles to parameterized SQL that you can inspect. No magic, no surprises.
- PostgreSQL first — we ship with a Postgres dialect and lean into its features. MySQL, SQLite, and other dialects are on the roadmap and will slot into the same architecture.
License
MIT
