Multiple Source Folders
Organize distinct concerns - public site, customer app, admin dashboard - as independent source folders within a single Vite project.
the composable meta-framework Multiple source folders. Directory-based routing. Cascading middleware. Nested layouts. End-to-end validation. Fetch clients. OpenAPI spec. Koa, Hono, SolidJS, React, Vue, MDX and more.
import { defineRoute } from "_/api";
export default defineRoute<
"users/[id]/{activity}",
[
// validate id param as number
number,
// activity, if given, should be one of
"posts" | "comments" | "likes",
]
>(({ GET }) => [
GET((ctx) => {
// ctx.validated.params is typed and validated at runtime
const { id, activity } = ctx.validated.params
})
]);json / form / raw. query, headers, cookies. VRefine to specify JSON Schema constraints. import { defineRoute } from "_/api";
type Payload = {
email: VRefine<string, { format: "email" }>;
password: VRefine<string, { pattern: "^(?=.*[a-zA-Z0-9])$" }>;
name: VRefine<string, { minLength: 5; maxLength: 50 }>;
dateOfBirth: VRefine<string, { format: "date" }>;
agreeToTerms: boolean;
marketingOptIn?: boolean;
}
export default defineRoute<"users">(({ POST }) => [
POST<{
json: Payload,
}>((ctx) => {
// ctx.validated.json is typed and validated at runtime
const { email } = ctx.validated.json;
})
]);import { defineRoute } from "_/api";
type Page = {
id: VRefine<string, { format: "uuid" }>;
title: VRefine<string, { minLength: 1; maxLength: 255 }>;
content: string;
tags: string[];
status: "draft" | "published" | "scheduled";
}
export default defineRoute<"pages/[id]">(({ GET }) => [
GET<{
response: [200, "json", Page],
}>(async (ctx) => {
// response should match defined schema
})
]);api/use.ts will run on every route. Routes can use slot option to override global middleware. logger should be added to api/env.d.ts file. import { use } from "_/api";
export default [
use(
(ctx, next) => {
// global logger
return next();
},
{ slot: "logger", },
),
];import { defineRoute } from "_/api";
export default defineRoute<"example">(({ use, GET }) => [
use(
async (ctx, next) => {
// custom logger
return next();
},
{ slot: "logger", },
),
GET(async (ctx) => {
// ...
}),
]);export declare module "@kosmojs/api" {
interface UseSlots {
logger: string;
}
}use.ts file in any folder, and its default exported middleware automatically wraps all routes in that folder and its subfolders - no imports or manual wiring required. import { use } from "_/api";
export default [
use(async (ctx, next) => {
// any route inside users/ folder and its subfolders
// will wire this middleware automatically
return next();
})
];KosmoJS is opinionated about organization, unopinionated about implementation.
It gives your full-stack project a consistent structure - multiple source folders, directory-based routing, end-to-end validation, cascading middleware, nested layouts, fetch clients etc. Everything works the same consistent way across every framework combination, backend or frontend.
Separation of concerns isn't something you have to remember; it's built into the core.
No proprietary abstractions. No new paradigms. Just structure on top of tools you already know.
π Learn more
Most projects start as one app and quietly become three - a marketing site, a customer app, an admin dashboard - each needing different routing, auth, and deploy strategies.
Source folders make this explicit from the start. Each gets its own api/ and pages/ directories, its own framework stack, its own base URL - while sharing types, validation logic, and infrastructure across a single project. The directory structure enforces boundaries that code review alone can't.
π Getting started Β· Directory-based routing
KosmoJS converts your TypeScript types into runtime validators, typed fetch clients, client-side validation, and OpenAPI schemas - all from the same definitions. No duplication, no drift.
π Type safety Β· Validation Β· Fetch clients
What you build locally is what deploys.
APIs run inside Vite's dev server with full hot-reload. Slot-based middleware gives you surgical control - override globals per-route or per-subtree, compose request handling without the usual middleware spaghetti.
π Dev workflow Β· Middleware
pnpm build produces a bundled API server, optimized frontend assets, and an optional SSR bundle - each deployable independently. Node.js, Deno, Bun, containers, serverless, or edge. Same build output, pick your runtime.
π Production build
Structure that scales. Choices that stay yours.
You pick the frontend framework, state management, styling, database, deploy target - everything. KosmoJS provides the organizational layer: routing conventions, validation pipeline, middleware composition, build orchestration. The kind of structure that's tedious to set up yourself and easy to let erode over time.
π About KosmoJS Β· Features