Skip to content

KosmoJS

A Vite-based full‑stack meta‑framework for type‑safe apps Multiple source folders. Directory-based nested routing. Runtime end-to-end validation. Generated fetch clients, OpenAPI spec. Koa, Hono, SolidJS, React, Vue and more.

Simple Params Validation

Require id to be a number
Details ➜
api/users/:id/index.ts
ts
import { defineRoute } from "_/admin/api/users/:id";

export default defineRoute<[
  number // validate id as number
]>(({ GET }) => [
  GET((ctx) => {
    // ctx.validated.params is typed and validated at runtime
    const { id } = ctx.typedParams
  })
]);
api/users/:id/index.ts
ts
import { defineRoute } from "_/admin/api/users/:id";

export default defineRoute<[
  // validate id as positive integer
  TRefine<number, { minimum: 1, multipleOf: 1 }>
]>(({ GET }) => [
  GET((ctx) => {
    // ctx.validated.params is typed and validated at runtime
    const { id } = ctx.typedParams
  })
]);

Refined Params Validation

Require id to be a positive integer.
Use TRefine to specify JSON Schema constraints.
Details ➜

Payload Validation

Use the first type argument to define the payload schema. TRefine can be used to specify JSON Schema constraints.
Details ➜
api/users/index.ts
ts
import { defineRoute } from "_/admin/api/users";

export default defineRoute(({ POST }) => [
  POST<{
    json: {
      email: TRefine<string, { format: "email" }>;
      password: TRefine<string, { pattern: "^(?=.*[a-zA-Z0-9])$" }>;
      name: TRefine<string, { minLength: 5; maxLength: 50 }>;
      dateOfBirth: TRefine<string, { format: "date" }>;
      agreeToTerms: boolean;
      marketingOptIn?: boolean;
    }
  }>((ctx) => {
    // ctx.validated.json is typed and validated at runtime
  })
]);
api/pages/:id/index.ts
ts
import { defineRoute } from "_/admin/api/pages/:id";

type Page = {
  id: TRefine<string, { format: "uuid" }>;
  title: TRefine<string, { minLength: 1; maxLength: 255 }>;
  content: string;
  tags: string[];
  status: "draft" | "published" | "scheduled";
}

export default defineRoute(({ GET }) => [
  GET<{
    response: [200, "json", Page], 
  }>(async (ctx) => {
    // response should match defined schema
  })
]);

Response Validation

Just as you validate incoming request data, you can validate outgoing response data by providing a tuple with status code, content type and expected schema.
Also an union of tuples can be used to specify multiple response variants.
Enabled by default on dev, disabled in production.
Details ➜

Global Middleware

Define middleware to run on every route. Use the slot option to allow routes to override this middleware later. Use the on option to run middleware only for specific HTTP methods.
Custom slots like auth should be added to api/env.d.ts file.
Details ➜
api/use.ts
ts
import { use } from "_/admin/api";

export default [
  use(
    (ctx, next) => { 
      // authentication logic here
      return next();
    },
    {
      slot: "auth", 
      on: ["POST", "PUT", "PATCH", "DELETE"],
    },
  ),
];
api/dashboard/index.ts
ts
import { defineRoute } from "_/admin/api/dashboard";

export default defineRoute(({ use, POST }) => [
  use(
    (ctx, next) => { 
      // no authentication for dashboard
      return next();
    },
    {
      slot: "auth", 
    },
  ),

  POST((ctx) => {
    // ...
  })
]);

Override Middleware

Use the slot option in routes to override global middleware with the same slot name.
Details ➜

🎯 The What ​

KosmoJS is a meta-framework that keeps your full-stack concerns aligned.

Rather than inventing yet another framework, KosmoJS integrates proven tools - TypeScript, Vite, Koa/Hono, and your frontend framework - into a clear organizational pattern. Separation of concerns isn't something you have to remember - it's built into the structure.

No proprietary abstractions. No new paradigms. Just thoughtful structure around tools you already know (or easy to learn).

πŸ“˜ Learn more


πŸ’‘ The Why ​

Multiple source folders for distinct concerns - each with its own API and pages directories, eg.:

πŸ”Ή Public marketing site at /
πŸ”Ή Customer application at /app
πŸ”Ή Admin dashboard at /admin

All in one monorepo-like project, each with independent routing and configuration, yet sharing types and validation logic.
API / Pages separation keeps server and client code from mixing. Your directory structure enforces boundaries that code review can't.

πŸ“˜ Getting started Β· Directory-based routing


πŸ“¦ The How ​

Being a Vite-based meta‑framework, KosmoJS unifies your frontend framework (Solid/React/Vue) with your backend choice (Koa/Hono) in a type‑safe, organized structure.

πŸ”Ή Vite handles your frontend builds and organizational structure.
πŸ”Ή Koa/Hono powers your API runtime with runtype validation and middleware composition.
πŸ”Ή KosmoJS is the structured template that brings them together.


πŸ›‘οΈ Type Safety & Validation ​

KosmoJS converts your types into runtime validation routines, ensuring type safety beyond compile time - no duplication, no drift.

Based on your parameter types, payload structures, and response shapes, KosmoJS generates:

  • Runtime validators for your API
  • Typed fetch clients for your frontend
  • Client-side validation that catches errors before requests
  • As well as OpenAPI schema for your entire API

Everything stays aligned because everything derives from the same source of truth - your types.

πŸ“˜ Type safety overview Β· Validation Β· Payload validation


⚑ Generated Fetch Clients ​

Every API route gets a fully-typed fetch client with built-in validation. Your frontend knows exactly what parameters each endpoint expects, what payload structure it accepts, and what response shape it returns.

Invalid data is caught client-side, before network requests. Your API never processes malformed requests.

πŸ“˜ Fetch clients intro Β· Getting started Β· Client-side validation


βš™οΈ API Development ​

Build APIs directly inside Vite's dev server with hot-reload support.

Slot-based middleware gives you fine-grained control - override global middleware per endpoint, compose request handling precisely, maintain consistent patterns across routes.

Development and production use the same structure - what you build locally is what deploys.

πŸ“˜ Dev workflow Β· Middleware patterns


πŸš€ Production Ready ​

pnpm build produces deployment-ready output:

  • a bundled API server
  • optimized frontend assets
  • an SSR bundle enabling smooth server-side rendering

Deploy to any Node.js environment: traditional servers, containers, serverless platforms, or edge runtimes.

πŸ“˜ Production build guide


🧠 Philosophy ​

Structure without constraints.

KosmoJS is opinionated about organization but unopinionated about implementation. Clear boundaries between API and pages. Obvious locations for shared types and utilities. Separation of concerns built into the filesystem.

You choose your frontend framework, state management, styling approach, database, and everything else.
The structure scales; your choices remain free.

πŸ“˜ About KosmoJS Β· Features


Released under the MIT License.