KosmoJS - the composable meta-framework

KosmoJS is a full-stack meta-framework for building several apps in one codebase. Each gets its own backend and frontend framework and its own routes; they all share one install, one set of types, one build.
You write features - KosmoJS handles the wiring.

Koa · HonoReact · Solid · Vue · MDXNode · Bun · Deno · WorkersMIT
a typical KosmoJS project at scale
src/
├─ shop/       /          React + Hono
├─ admin/      /admin     Solid + Koa
├─ webhooks/   /hooks     Hono, no UI
├─ docs/       /docs      MDX, no API
└─ status/     /status    Vue + Hono
- any number of folders, any stack each

composable by nature

A project is never just one app.

New surfaces keep appearing - each wants its own routing, auth, and deploy story. The usual ways of splitting them apart all add maintenance overhead.

Microservices

Separate repos, separate pipelines, separate deploy configs. Shared types drift. A schema change turns into a cross-repo negotiation, and you spend more time on infrastructure than features.

Monorepos

One repo, but now you maintain workspaces, package boundaries, internal dependency graphs, and build caches. The packages/shared folder slowly becomes a junk drawer. The tooling becomes its own project.

DIY glue

Hand-wired scripts and a homegrown dev server that stitches the apps together. Cheap to build. Then a second developer joins and asks why start-all.sh passes --legacy-peer-deps - and nobody remembers.

built on Vite

Source folders.

One folder per concern. A source folder is whatever you need it to be - a public site, an internal tool, a backend-only webhook handler, a docs site - each with its own backend and frontend framework, base URL, and build output. None of them are separate packages.

  • OKOne package.json, one node_modules, one set of types shared across every folder.
  • OKNeed a type from the customer app in the admin panel? Import it. Change a model and every folder sees it immediately.
  • OKOne command starts them all. One builds them all. Or build a single folder when that is all you need.
  • OKNo publishing, no versioning, no workspace protocols. The directory structure enforces boundaries code review can't.

connected apps, provisioned

Structure and toolchain provided - you just add features.

You no longer manage repos or wrestle configs - you write business logic. Define a route, and request validation, type-safe fetch clients, and an OpenAPI spec are generated from it. Cascading middleware removes the import-and-wire busywork; nested layouts and anything your chosen framework supports stay available. KosmoJS adds no proprietary abstractions to fight - you keep direct, full access to the frameworks underneath.

TSapi/users/index.ts
import { defineRoute } from "_/api";

export default defineRoute<"users">(({ POST }) => [
  POST<{
    json: {
      name: string;
      email: VRefine<string, { format: "email" }>;
    };
  }>(async (ctx) => {
    const { name, email } = ctx.validated.json;  // validated, typed
    ctx.body = await createUser(name, email);
  }),
]);
pages/users/index.tsxReact
// import generated clients
import fetchClients from "_/fetch";

const { POST } = fetchClients["users"];

export default function Page() {
  const form = useForm({ name: "", email: "" });

  // fully typed and validated client-side
  const submit = () => POST([], { json: form.values });

  return <UserForm form={form} onSubmit={submit} />;
}

[id] required · {id} optional · {...path} splat identical syntax for API routes and pages. Solid, Vue and MDX pages follow the same shape.

what you get

Structure where it pays off.

With all features enabled out of the box, you forget about the tedious parts of a full-stack project. Multiple sub-projects merge into one coherent, scalable structure - which you don't have to maintain.

[ ]/

Directory-based routing

Your folder tree is the route map, for API and pages alike. Nothing to keep in sync.

<T>

End-to-end type safety

Write the type once. Runtime validation, a typed client, and OpenAPI all derive from it.

Generated fetch clients

Every route gets a typed client. Invalid requests fail in the browser, before a round trip.

{ }

OpenAPI 3.1, free

A spec falls out of the same definitions - no annotation layer, no hand-authored schema.

Cascading middleware

Drop a use.ts in any folder; it wraps everything beneath it. No imports, no wiring.

Composable slots

Override one piece of global middleware per route or subtree. Inherit everything else.

Nested layouts

Compose shared shells - nav, sidebars, auth - at any depth. The file system is the hierarchy.

Built on proven tools

No proprietary runtime, no custom bundler. Every layer is something you can debug and swap.

how it differs

Opinionated about structure. Unopinionated about everything else.

Most meta-frameworks pick your frontend for you and own your deploy model. Monorepo tools hand you flexibility and a configuration tax. Microservices give independence and a fragmented codebase. KosmoJS keeps the part that is tedious to set up and easy to let erode - routing conventions, the validation pipeline, middleware composition, build orchestration - and leaves the rest to you: frontend, state, styling, database, deploy target.

Structure that scales. Choices that stay yours.

Zero to a working route in five minutes.

Scaffold a project, add a source folder, pick your stack. The dev server does the rest.

$ pnpm create kosmo