Skip to content

Every source folder runs one frontend framework - React, SolidJS, Vue, Svelte or MDX - picked when you create the folder. Different folders can run different ones in the same project.

Whichever you choose, the shape of the work is the same: components under pages/ become the routes, navigation and data loading are typed end to end, and page code is split automatically.

Nothing about the framework itself changes - you keep its router, its reactive model and its ecosystem, exactly as documented upstream.

What's in the Folder

These are the files that make the folder an application. Every one is a real source file you own: written once when the folder is created, never re-seeded behind your back, and - unlike page route files - never seeded through custom templates.

text
src/<folder>/
├── kosmo.config.ts       -> this folder's config (and its Vite config)
├── tsconfig.json         -> extends lib/front/tsconfig.json
├── index.html            -> Vite's HTML entry
├── app.tsx               -> global wrapper around EVERY route
├── router.ts             -> wires routes into the native router

├── entry/
│   ├── client.ts         -> mount vs hydrate, in the browser
│   └── server.ts         -> renderToString / renderToStream  (SSR only)

├── components/
│   └── Link.tsx          -> typed Link component

└── pages/
    ├── 404.tsx           -> rendered for unmatched routes
    ├── index/
    │   └── index.tsx     -> the route  ➜  /
    └── users/
        ├── layout.tsx    -> wraps everything under /users
        └── [id]/
            └── index.tsx -> the route  ➜  /users/:id

Foundation files

FileWhat it isWhen you touch it
app.*The global wrapper, rendered around every route including 404 - the place for providers, auth gates, analytics, an app-wide error boundary. Not a layout: it has no folder scope, it simply wraps everything.Providers, global chrome
router.tsrouterFactory - hands your app plus the derived routes to the framework's native router, returning clientRouter() for browser navigation and serverRouter(url) for SSR.Rarely
entry/client.*The browser entry, referenced from index.html. renderFactory picks mount() (fresh render) or hydrate() (SSR markup already present) automatically.Rarely
entry/server.*The SSR entry, exporting renderToString and - where the framework supports it - renderToStream. Only present when SSR is enabled.Injecting SSR assets into head
components/Link.*The typed Link component: to takes a [routeName, ...params] tuple, so renaming a route directory becomes a compile error at every call site.Styling it
index.htmlVite's HTML entry, loading entry/client.Meta tags, fonts, the mount node
tsconfig.jsonExtends the derived lib/<folder>/tsconfig.json, which carries JSX and path settings. Anything you set here wins.Relaxing strictness
kosmo.config.tsThe folder's configuration - the frontend, backend and validation blocks, and any Vite option.Turning on SSR, adding Vite plugins

Inside pages/

FileWhat it is
<route>/index.*The route. Its folder path becomes the URL.
<route>/layout.*Wraps that folder and everything beneath it. Only works inside a route folder. Details ›
404.*The catch-all error page for unmatched URLs.
anything elseA colocated helper - never a route.

Extensions per framework

router.ts and entry/* are always .ts; everything else follows the framework:

ReactSolidJSVueSvelteMDX
App fileapp.tsxapp.tsxapp.vueapp.svelteapp.mdx
Pageindex.tsxindex.tsxindex.vueindex.svelteindex.mdx / .md
Layoutlayout.tsxlayout.tsxlayout.vuelayout.sveltelayout.mdx
Error page404.tsx404.tsx404.vue404.svelte404.mdx
LinkLink.tsxLink.tsxLink.vueLink.svelteLink.tsx
Extracomponents/mdx.ts (component map)

A source folder runs exactly one framework and ignores the others' files - a Vue folder never picks up a stray .tsx page. Full matrix ›

Derived code - the route table, fetch clients, validators - lives in lib/, is git-ignored, and is not something you read to learn the project. Why codegen ›

TypeScript Configuration

Mixing frameworks across source folders requires per-folder TypeScript configuration. Each framework has its own JSX import source requirement:

FrameworkjsxImportSource
React"react"
SolidJS"solid-js"
Vue"vue" (only when using JSX)
Svelten/a (no JSX - compiled from .svelte)
MDX"preact"

KosmoJS delegates JSX transformation to Vite, not TypeScript - but differing jsxImportSource values cause type conflicts when multiple frameworks coexist in the same project.

Solved by deriving a tsconfig.json specific to each source folder, placed in the lib/ directory for the source folder to extend:

src/front/tsconfig.json
json
{ "extends": "../../lib/front/tsconfig.json" }

Each config supplies the correct jsxImportSource, path mappings, and core settings.

What Differs Between Frameworks

Routing, layouts, validation and the fetch clients behave identically everywhere. Data loading, streaming support, SSG, TanStack Query and the exotic routing syntaxes do not - those differences are collected in one table:

Framework Support Matrix ›

Released under the MIT License.