@shaferllc/keel
v0.87.0
Published
The house framework for Node.js — a service container, providers, routing, JSX views, and a code-generating console.
Maintainers
Readme
Keel ⚓
The house framework for Node.js.
TypeScript · a real service container · convention-driven structure · a code-generating console.
Getting Started · Container · Routing · Providers · Console
Keel gives you the ergonomics that make you productive — a service container, service providers, dot-notation config, expressive routing, and a code-generating console — on a modern TypeScript stack. Hono powers the HTTP layer under the hood; everything above it is Keel's.
It is a house framework: small enough to read in an afternoon, opinionated enough to ship on, and yours to extend.
// routes/web.ts
router.get("/", [HomeController, "index"]);
router.get("/hello/:name", (c) => c.text(`Hello, ${c.req.param("name")}!`));// A controller — resolved from the container, so it gets dependency injection
export class HomeController {
constructor(private app: Container) {}
index(c: Ctx) {
return c.json({ app: config("app.name") });
}
}Why Keel?
- A real service container.
bind/singleton/instance/make. Everything resolves through it — the pattern that keeps apps testable and composable. - Service providers. A
register()→boot()lifecycle to configure the app in one place. - Convention over configuration.
app/,config/,routes/,bootstrap/— you always know where things live. - A code-generating console.
keel serve,keel routes, andmake:*generators. - Typed end to end. Strict TypeScript, no build step in dev (powered by
tsx). - Thin and legible. The whole framework is a few hundred lines in
src/core/. No magic you can't read.
Two pieces: the framework and your app
Keel is a library you install. New apps come from the generator (templates ship inside the package so they cannot lag the framework):
npm create keeljs@latest my-app
cd my-app && npm install && npm run devEnd-to-end (local → Cloudflare or optional Keel Cloud): From install to deploy.
Deploy on *.keeljs.cloud from your IDE (same keel-mcp + a Cloud token):
Keel Cloud — deploy from MCP.
| Repo | Role |
|------|------|
| shaferllc/keel (this repo) | The framework. Published as @shaferllc/keel. |
| Your app (via create-keeljs) | Routes, models, views — depends on @shaferllc/keel. |
Install in your app
npm create keeljs@latest my-app
# or, into an existing project:
npm install @shaferllc/keelimport { Application, Router, config } from "@shaferllc/keel/core";Hack on the framework itself
git clone https://github.com/shaferllc/keel.git
cd keel
npm install
npm test
npm run typecheck
npm run build
npm run verify:releasePoint a generated kit at your checkout with
"@shaferllc/keel": "file:../keel" while developing.
The console
keel routes # list every registered route
keel serve --port 8080 # start the server on a chosen port
keel make:controller Post # -> app/Controllers/PostController.ts
keel make:provider Billing # -> app/Providers/BillingServiceProvider.ts
keel make:middleware Auth # -> app/Http/Middleware/authMiddleware.ts
keel make:page users/[id] # -> resources/pages/users/[id].tsx
keel make:command greet # -> app/Commands/greet.ts
keel repl # a shell with the app booted
keel mcp # start the MCP server (docs + API for AI agents)These run in your app, from its own bin/keel.ts — which is a few lines that
hand the console your application factory (see the console guide).
Built for AI ⚓🤖
Keel is designed to be written with an AI agent. Alongside the human docs it ships a machine-readable surface that stays generated-in-sync, never stale:
- An MCP server.
keel-mcpexposes Keel's docs, its full public API (380+ exports), the generators, and its conventions to any MCP client — and withKEEL_CLOUD_TOKEN, deploys sites to*.keeljs.cloud(create_site→ preview → publish). See Keel Cloud. Connect it anywhere:
Tools:curl -fsSL https://keeljs.com/install.sh | bash # or: npx -y keel-mcp@latest init # Cloud: … | bash -s -- --token "$KEEL_CLOUD_TOKEN" --claudekeel_overview,keel_search_docs,keel_read_doc,keel_search_api,keel_list_generators,keel_scaffold, pluskeel_cloud_*when a token is set. Resources:keel://overview,keel://llms-full,keel://docs/<slug>. AGENTS.md. The agent playbook — the one import rule, the folder map, the container/provider model, a "how to add X" table, and the guardrails.CLAUDE.mdpoints to it.llms.txt+llms-full.txt. A spec-compliant doc index and a one-file concatenation of every guide, both shipped in the npm package for drop-in context.- Generators an agent can drive.
keel_scaffold(orkeel make:*) emits the correct stub with the right imports and path for every construct.
Full guide: docs/ai.md. Regenerate the surface after doc or
export changes with npm run build:ai (also runs automatically on npm run build).
Project layout
src/core/ The framework
├─ container.ts Service container — bind / singleton / instance / make
├─ application.ts Kernel: env + config loading + provider lifecycle
├─ config.ts Dot-notation config repository + env() helper
├─ provider.ts ServiceProvider base class (register / boot)
├─ http/
│ ├─ router.ts Route facade (closures or [Controller, method] tuples)
│ └─ kernel.ts Global middleware + compiles routes onto Hono
├─ cli/ The console: commands, generators, the kernel that runs them
└─ index.ts Public surface — apps import "@shaferllc/keel/core"
src/db/ Database adapters (D1, Postgres, libSQL)
src/api/ CRUD REST resources from a model
src/openapi/ Generates an OpenAPI spec from the routes
src/billing/ Subscription billing — Stripe + Paddle
src/gates/ Signup gates — invite codes & email allowlist
src/hosting/ Cloudflare / dump / secrets helpers for hosted apps
src/watch/ The debug dashboard
src/mcp/ The MCP server (docs + API for AI agents)
src/vite/ The Vite plugin
tests/ 767 tests
docs/ Every guide, plus type-checked examples of each
scripts/ build-ai (llms.txt, the MCP manifest), verify-releaseThere is no app/ here. Your application code — controllers, providers,
routes, config — lives in your repo, not the framework's. The
starter app has the layout.
The request lifecycle
bin/keel.ts servecallscreateApplication()inbootstrap/app.ts.- The
Applicationloads.env, then everyconfig/*.tsfile, then runs each provider'sregister()andboot(). - The HTTP kernel (
app/Http/Kernel.ts) applies global middleware and compiles the collected routes onto a Hono instance. @hono/node-serverserves it. Each request flows through middleware → route handler (a closure or a container-resolved controller) → response.
See docs/architecture.md for the full picture.
Documentation
| Guide | What it covers |
|-------|----------------|
| Getting Started | First route, controller, view, config |
| From install to deploy | create-keeljs → local → Cloudflare or Keel Cloud |
| Keel Cloud | Deploy *.keeljs.cloud from keel-mcp (create → preview → publish) |
| Starter kits | Presets (minimal / api / app / saas) |
| The Service Container | Binding and resolving services, DI |
| Service Providers | Plugin system: register/boot lifecycle, options |
| Configuration | config/*.ts, dot-notation, env() |
| Routing | Closures, controller tuples, groups, resources, domains |
| URL Builder | Named-route URLs, signed URLs |
| Hashing & Encryption | Password hashing, AES value encryption |
| Controllers | Classes, DI, single-action, lazy-loaded |
| Request & Response | Input, cookies, output, abort() |
| Request Decorators | Lazy, memoized per-request values |
| Lifecycle Hooks | onReady/onShutdown, graceful shutdown, onRoute |
| Sessions | Cookie-backed sessions, flash messages |
| Authentication | Session auth, guards, user provider |
| Gates | Signup gating — invite codes & email allowlist |
| Hosting | Cloudflare, SQL dump, secrets for hosted Workers |
| Authorization | Ability gates & policies, can/authorize |
| Database | Driver-agnostic query builder |
| Models | Active-record: find/create/save, casts, relations |
| Migrations | Schema builder + migrator, dialect-aware |
| Factories & Seeders | Built-in Faker, model factories, seeders |
| Mail | Fluent mailer, pluggable transports, sendLater(), attachments |
| Queues & Jobs | Dispatch jobs, retries + backoff, dead-letter, workers |
| Task Scheduling | Cron-style recurring tasks, one trigger |
| Notifications | Multi-channel (mail/db), queueable |
| Broadcasting | Real-time channels, pluggable, presence auth |
| API Resources | CRUD REST API from a model; deny-by-default access, row-level scope |
| Transformers | Shape models into API JSON; conditional fields, relations |
| Events | Emit/listen decoupling, async listeners |
| Service Broker | Moleculer-style services, call/emit, pluggable transport |
| Cache | TTLs, the remember pattern, pluggable stores |
| Locks | Distributed locks with ownership + TTL, pluggable stores |
| Redis | Pluggable client, memory driver, cache adapter |
| Logger | Structured logging, sinks, per-request reqId, redaction |
| Static Files | serveStatic(), caching, dot-file safety |
| Storage | Pluggable disks (local/S3/R2), signed URLs, direct uploads |
| Health Checks | /health/live + /health/ready, pluggable checks |
| Telemetry | Tracing, W3C context, OTLP export — no SDK |
| Internationalization | ICU messages, Intl formatters, locale detection |
| Pages | Page-based routing — a file is a route |
| Packages | Redistributable slices of an app: routes, migrations, commands |
| Billing | Subscriptions, charges & webhooks — Stripe + Paddle |
| Watch | Debug dashboard — requests, queries, jobs, logs at /watch |
| Views | Hono JSX components, layouts, the View service |
| UI | Design kit — tokens, components (@shaferllc/keel/ui) |
| Templates | {{ }} + @-tag templating engine, edge-safe |
| Middleware | Global middleware, writing your own |
| Rate Limiting | rateLimiter() middleware, per-key buckets |
| Errors | HTTP exceptions, debug page, custom handlers |
| Testing | Inject requests, fakes, spies, time travel, db assertions |
| Debugging | dump() and dd() (dump-and-die) |
| Validation | validate() with Zod, auto-422 field errors |
| Inertia | Server-side Inertia.js adapter |
| Vite | Frontend build: HMR in dev, hashed manifest in prod |
| The Console | Typed commands, prompts, terminal UI, REPL, make:* |
| Architecture | Container, kernel, request lifecycle |
| Built on Hono | The Hono layer underneath, and using it directly |
| Building with AI | MCP server, AGENTS.md, llms.txt, agent workflow |
Testing
The core has a test suite (Node's built-in runner + tsx, no extra tooling):
npm test # run the suite
npm run test:coverage # with v8 coverageUnit tests cover the container, config, view, exceptions, and validation; an integration suite drives the HTTP kernel end-to-end (routing, request/response helpers, error rendering, middleware, validation). Coverage sits at ~99% lines / ~91% branches.
Requirements
- Node.js ≥ 22
- No database or build step required for the MVP core.
Roadmap
The MVP core and the major subsystems are shipped. Recent focus is Keel Cloud support (gates, hosting, MCP Cloud tools, billing portal) and starter kits. See CHANGELOG.md for release history.
Contributing
Issues and PRs welcome. Run npm run typecheck before opening a PR.
License
MIT © 2026 Tom Shafer
