Skip to content

noormA CLI for SQL-first database development.

Manage SQL files, track changes, and run builds across dev, staging, and production—no ORM required.

noorm TUI demo

Why noorm?

noorm is a command-line tool for managing SQL-first database applications. It handles everything ORMs won't touch: compound keys, check constraints, triggers, stored procedures—the full relational model.

What it does:

  • SQL files define your current schema—no migration archaeology
  • Changes evolve existing databases from any state to current
  • Stages manage dev, staging, and production with different configs
  • SDK provides type-safe programmatic access to your database

You write SQL. noorm executes it, tracks what ran, and keeps multiple environments in sync.

The Case for Proper Relational Design

ORMs push you toward a pattern: every table gets a surrogate ID, relationships happen through foreign keys, and you join your way back to find what you need. It works—until you're seven joins deep trying to figure out which user owns a deeply nested entity, and your messy left joins are adding NULL rows or creating cartesian products.

Proper relational design uses inherited keys. Instead of giving every entity an independent identity, child entities inherit their parent's key as part of their own.

Example: A todo list

users
  → user_id (surrogate, this is the root)

todos
  → user_id + created_at (inherits from user, no separate todo_id)

todo_items
  → user_id + created_at + item_index (inherits from todo)

With inherited keys, a todo_item carries its lineage in its identity. You don't need joins to find the user—it's right there in the key. The deeper your schema goes, the more this matters.

Try working that into your ORM. I'll wait...

Furthermore: Polymorphism Basetype-Subtypes

ORMs love polymorphic associations: a comments table with commentable_type and commentable_id. Fast, flexible—and completely breaks referential integrity. Complex app logic, no foreign keys, slow and awkward statistics, and even more awkward queries.

Proper relational design solved this years ago with basetype-subtypes:

independent entities: user, group
dependent entities:   profile
basetype-subtypes:    post     → user_post, group_post
                      photo    → user_photo, group_photo, profile_photo, user_post_photo, ...
                      comment  → user_comment, group_comment, post_comment, comment_comment, ...
                      tag      → post_tag, photo_tag, comment_tag, ...

Each relationship gets its own table with proper constraints against its parent. A user_post has a foreign key to user and post. A group_photo has a foreign key to group and photo. No nulls, no type columns, no ambiguity.

You work with existence and non-existence—not "maybe exists" or calculate. You depend on physical existence, not hopeful logic. Statistics are straightforward. Queries are clean. The database enforces integrity at every level. Illegal states become impossible. The trade-off is more tables, but the benefit is less app logic.

You pay for bad relational design later in complexity and bugs.

Quick Start

bash
# Install
npm install -g @noormdev/cli

# Launch the TUI
noorm

From the terminal interface, set up your project:

  1. [i] Identity — Set your name (for team tracking)
  2. [c] Config → [a] Add — Create a database config
  3. [r] Run → Build — Execute your SQL files

Or use headless mode for scripting:

bash
noorm -H init
noorm -H identity set "Your Name"
noorm -H config add
noorm -H run build

Create your SQL files:

bash
mkdir -p sql/01_tables
echo "CREATE TABLE users (id SERIAL PRIMARY KEY, name TEXT);" > sql/01_tables/001_users.sql

Build your schema:

bash
noorm -H run build
✓ Executed 1 file

Now your schema needs to evolve. Update your SQL file AND create a change:

bash
# Update sql/01_tables/001_users.sql (add email column)
# Create changes/2024-01-add-email/forward.sql

noorm -H change ff     # Fast-forward: apply pending changes

Need a fresh test database? Create another config and build—no changes needed:

bash
noorm -H config add    # Create test config
noorm -H run build     # Fresh DB gets current schema directly

SQL files = current schema. Changes = how to get existing databases there.

Next Steps

Installation Get noorm installed and running.

First Build Complete the tutorial and see the core value.

Building Your SDK Create a type-safe database package for your apps.