The module registry is live

The composable
backend framework
for TypeScript

Open source, built on Bun. Assemble models, services, routes, and workflows from plug-and-play modules — installed with one command, wired to your database and HTTP server at startup.

Start buildingView on GitHub$damat create

Modules

Self-contained features you author in isolation and install anywhere.

ORM

Typed models over PostgreSQL with real migrations and generated CRUD.

HTTP

File-based routes on Hono with per-route validation and middleware.

Workflows

Multi-step sagas with retries, timeouts, and compensation.

Agent tools

One CLI for everything — exposed to AI agents over MCP.

my-appone command, fully wired
terminal
$damat module add damatjs/user@0.2.0
resolving from registry.damatjs.com
owner damatjs — verified
module copied → src/modules/user
registered "user" in damat.config.ts
env keys synced → .env
$bun damat-orm migrate:up
4 tables — users, accounts, sessions, verifications
$damat dev
listening on :6543 — user module mounted
$
damat.config.ts
import { defineConfig } from "@damatjs/framework"; export default defineConfig({  projectConfig: {    databaseUrl: process.env.DATABASE_URL!,    redisUrl: process.env.REDIS_URL,    http: { port: 6543 },  },  modules: {    user: { resolve: "./src/modules/user", id: "user" }, // ← added  },});
wired at startupmodelsmigrationsroutesworkflowsenv vars
Bun
Hono
Effect-TS
PostgreSQL
Redis
TypeScript

Framework

Everything a backend needs, nothing bolted on.

Each capability is a first-class part of the framework — built to compose with the others, documented end to end, and replaceable module by module.

Developer experience

A module, end to end.

Real Damat code, not pseudocode. Define a model and the table, migration, and CRUD service come with it. Add a route file and it mounts. Failed workflow steps roll themselves back.

  • Table names are the source of truth — keys, routes, and relations derive from them.
  • Services extend generated CRUD with your domain methods and transactions.
  • Compensation runs in reverse when a workflow step fails.
Follow the guide from zero
src/modules/user/models/user.ts
import { model, columns } from "@damatjs/orm-model";

export const UserModel = model("users", {
  id: columns.id({ prefix: "usr" }).primaryKey(),
  email: columns.text().unique(),
  emailVerified: columns.boolean().default(false),
  name: columns.text().nullable(),

  // relations reference the target table name
  accounts: columns.hasMany("accounts"),
  sessions: columns.hasMany("sessions"),
})
  .indexes([columns.indexes().columns(["email"]).unique()])
  .timestamps(); // adds createdAt / updatedAt

The registry

Modules install like dependencies.

Pull a module from the registry, a git URL, or a local path. Every registry entry carries an owner and a verification status — gate installs with DAMAT_MODULE_VERIFY=require.

damatjs/userv0.2.0Verified

Authentication, sessions and accounts — drop-in users, credentials, and session management for any Damat app.

$ damat module add damatjs/user@0.2.0
billingv0.1.0Community

Stripe subscriptions and one-time credits — plans, checkout, webhooks, and a credits ledger.

$ damat module add billing@0.1.0

your-org/your-module

Scaffold a module offline with damat module init, build and test it on its own, then publish it from any git repo.

Author your first module
your agent, over MCP

Add auth to my app.

⚙ add_module { source: "damatjs/user" }

✓ registered "user" in damat.config.ts

✓ env keys synced → .env

Done — run bun damat-orm migrate:up to apply the 4 new tables.

Changelog

Shipping in lockstep.

Every package releases together under one version, each with a before/after note and exact upgrade steps — no archaeology required.

v1.0.0

  • @damatjs/provider-authDamat ships a strict auth service contract, not a vendor adapter or identity engine.
  • @damatjs/cliThe core CLI becomes a framework-neutral, embeddable runtime with injected process boundaries and invocation-local state.

+27 more packages

v0.6.0

  • @damatjs/create-damat-appGit and shell commands run through execFile with argument arrays instead of interpolated shell strings, and the scaffolder reports its build-time version.
  • @damatjs/damat-clidamat module add becomes safe by default: non-registry sources and lifecycle scripts require explicit opt-in flags, module ids and paths are validated before anything is written, and the CLI reports its real version.

+10 more packages

v0.5.0

  • @damatjs/frameworkNon-Error throws (throw "boom", throw { code: 1 }) are no longer silently swallowed by the error middleware — they are stringified, logged, and surfaced in dev responses.
  • @damatjs/orm-migrationPer-module migration discovery now sorts numerically by timestamp (with the filename as tiebreaker), matching all-module discovery — the same migrations run in the same order no matter which entry point discovered them.
All releases

Open source

One public repo. Nothing held back.

The framework, the ORM, the workflow engine, the CLI, the docs, and the registry index all live side by side in a single MIT-licensed monorepo. What you deploy is code you can read — and every release ships a note saying exactly what changed and how to move to it.

current release — every package moves in lockstep
v1.0.1current release — every package moves in lockstep
published packages, one public monorepo
36published packages, one public monorepo
guide chapters, from first model to deployment
26guide chapters, from first model to deployment
licensed — no open core, no paid tier
MITlicensed — no open core, no paid tier

FAQ

Questions, answered.

The short version of what people ask first. Everything here is covered in depth in the guide.

What is Damat?

Damat is an open-source, composable backend framework for TypeScript on Bun. You assemble a backend from plug-and-play modules — models, services, HTTP routes, and workflows — wired to PostgreSQL and an HTTP server at startup.

How is Damat different from a starter template?

A starter template copies code into your repo that you maintain forever. A Damat module is a versioned, self-contained package: installing it wires its models, service, config, and migrations into your app, and upgrading it is a version bump rather than a manual merge.

Where do modules come from?

Three sources: the module registry (entries carry an owner and a verification status), any git URL pinned to a branch or tag, or a local path on disk. Installs can be gated to verified entries with DAMAT_MODULE_VERIFY=require.

What does Damat run on?

Bun as the runtime, Hono for HTTP, Effect-TS for typed business logic, PostgreSQL as the system of record, and Redis for caching — all strict-mode TypeScript end to end.

Can AI assistants work with Damat?

Yes. Damat ships an MCP server that lets AI assistants list, search, inspect, and install registry modules directly into an app.

Is Damat open source?

Yes — MIT licensed, developed in a single public monorepo on GitHub. All packages release in lockstep, so there is one version to care about.

Start with one command.

Scaffold an app, define a model, install a module, ship. The guide takes you from zero to a running backend.

$damat createRead the guide