Scaffolding
Every Kyln project starts with kyln preheat: one command that writes a working project from a template, installs dependencies, and leaves you ready to run. There are four templates, one per project shape. They all sit on the same framework, so picking one is a starting point, not a commitment; moving between shapes means adding directories, not migrating.
The preheat workflow
Install the CLI once, globally. That puts the kyln command on your PATH, and every command from here on is plain kyln:
bun add -g @kyln/cliRun kyln preheat bare and it goes interactive: a menu picks the template and prompts for the project name.
kyln preheatOr name the template and project directly:
kyln preheat webapp my-appTo scaffold into a directory that already has files (a README.md, a .git/ history), pass --into-existing. It writes per-file and skips anything that already exists, so nothing you manage gets clobbered:
kyln preheat webapp . --into-existingPrefer not to install globally? bunx @kyln/cli <command> runs any command without installing.
webapp: the full-stack app
The batteries-included starting point: pages, components, API endpoints, services with dependency injection, Tailwind CSS wired up, and a small task-tracker demo showing the pieces working together. Choose it when you're building an application people open in a browser. If in doubt, start here; it contains every other shape.
my-app/
├── kyln.config.ts # server, router, and build options
├── package.json
├── tsconfig.json
├── src/
│ ├── routes/ # pages; the filesystem is the router
│ │ ├── _layout.ts # wraps every page
│ │ ├── index.route.ts
│ │ ├── tasks.route.ts # the task-tracker demo
│ │ ├── login.route.ts
│ │ ├── register.route.ts
│ │ ├── about.route.ts
│ │ └── [...catchall].route.ts # the 404 page
│ ├── components/ # navbar, task-card
│ ├── services/ # auth + db (bun:sqlite), wired with DI
│ ├── api/ # /api/tasks and /api/user endpoints
│ └── styles/ # Tailwind entry point
└── tests/Scheduled tasks run the moment you add a src/scheduled/ directory.
kyln preheat webapp my-appfrontend: pages and components only
The client-facing slice: routes, components, and reactivity with no server-side code, and Tailwind CSS wired up. Choose it for sites and UIs that don't need their own backend. It grows the same way every template does; add a src/api/ directory when the project earns one, and the endpoints join the same app.
my-site/
├── kyln.config.ts # server and router options
├── bunfig.toml # preloads the test DOM
├── test-setup.ts # happy-dom registration for tests
├── package.json
├── tsconfig.json
├── src/
│ ├── routes/ # pages; the filesystem is the router
│ │ ├── _layout.ts # wraps every page
│ │ ├── index.route.ts
│ │ └── about.route.ts
│ ├── components/ # nav, footer
│ └── styles/ # Tailwind entry point
└── tests/ # component render testsComponent tests work out of the box: the template ships a happy-dom test setup (bunfig.toml preloads it), so kyln test renders and asserts against components with nothing extra to install.
kyln preheat frontend my-siteapi: the JSON service
An API-only service: @api endpoint classes, services with dependency injection, and tests, with no pages and no client bundle. Choose it for microservices and backends that speak JSON.
my-service/
├── kyln.config.ts
├── package.json
├── tsconfig.json
├── src/
│ ├── api/ # /api/widgets CRUD demo + /api/health
│ ├── services/ # widgets + db (bun:sqlite), wired with DI
│ └── routes/ # empty on purpose; drop in a route file to add pages
└── tests/ # endpoint testssrc/routes/ ships empty by design. Drop a route file in it later and the service grows a front-end without changing shape.
kyln preheat api my-servicetaskrunner: background jobs
A scheduled-jobs service: @Cron and @Interval tasks, services, tests, and a minimal health endpoint so you can tell it's alive. Choose it when the work runs on a clock rather than in response to requests. Scheduled tasks covers writing the tasks themselves.
my-jobs/
├── kyln.config.ts
├── package.json
├── tsconfig.json
├── src/
│ ├── scheduled/ # daily-cleanup (@Cron) and heartbeat (@Interval)
│ ├── services/ # heartbeat state (bun:sqlite)
│ ├── api/ # /api/health
│ └── routes/ # empty on purpose
└── tests/kyln preheat taskrunner my-jobsWhat's in the box
webapp, api, and taskrunner include @kyln/scheduler, so scheduled tasks are one src/scheduled/ directory away with nothing to install. frontend deliberately leaves it out; a pure client project has no use for a job scheduler, and bun add @kyln/scheduler brings it in if that changes.
Next
Scaffolded and running, your project's pages come from the filesystem. Routing & layouts covers how files become URLs.