Skip to content

seasonedcc/composable-controllers

Repository files navigation

composable-controllers

Composable HTTP controllers for TypeScript. Web-standards-first, framework-extensible. Pairs with composable-functions for business logic.

Status: v0.x — under active development. API is unstable and may change without notice.

Packages

Package Description
@composable-controllers/core Generic types, parsers, the Step<T, R> algebra, response finalizers, and the controller(...) builder. Web-standards-only (Request → Response).
@composable-controllers/react-router React Router v7+ adapter. Provides toAction/toLoader adapters, RR-shaped finalizers, and the act/load recipes.

Why

Controllers in remaster apps had drifted into a familiar shape: a 2-line shim that mounts framework context, delegates to a business Composable, and reshapes the Result for the wire — but every app re-implemented the wiring inline. This library extracts that discipline.

Three composition layers, deliberately separate:

  1. Business — write your domain logic as composable-functions Composable values.
  2. Result-transformer algebra — observe a business Result<T> and either pass it through or terminate with a response. Step<T, R>s compose; named helpers (redirectOnSuccess, surfaceError, notFoundIf, traceErrors) cover the common shapes.
  3. Controller constructioncontroller({ parse, run, transforms, finalize }) assembles a typed parser, the business call, the transformer chain, and a final responder into a single Controller<R, Ctx>.

Per-framework packs (just RR for now) layer on adapters and recipe-level conveniences.

Quick taste

// app/routes/users.new.tsx
import { act, redirectOnSuccess } from '@composable-controllers/react-router'
import { createUser, createUserSchema } from '~/business/users.server'

export const action = act(createUserSchema, createUser, {
  transforms: [redirectOnSuccess(() => '/users')],
})

A working app is in examples/react-router-app.

Local development

pnpm install
pnpm tsc           # type-check all packages + example
pnpm test          # run vitest in every package
pnpm build         # build core, then the RR pack
pnpm lint          # biome check

The example app:

pnpm --filter @composable-controllers/example-react-router-app dev

Boots an RR v7 dev server. /users exercises the load recipe; /users/new exercises act end-to-end.

Releasing

Releases are driven by Claude Code via .claude/skills/release/SKILL.md. The maintainer says "release"; the skill analyzes the diff, drafts a changeset, runs checks, commits, asks for a pnpm release (npm OTP required), and creates per-package GitHub releases.

License

MIT © Seasoned

About

Composable HTTP controllers for TypeScript. Web-standards-first, framework-extensible. Pairs with composable-functions.

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors