Start here
Project anatomy
A Stone.js project is small and its shape mirrors the architecture: your domain in one place, the manifest that gives it a context in another, and a thin layer of build config. There is very little framework to see.
#The layout
app/
Application.ts the manifest: adapters and app-wide config live here
Tasks.ts your domain: services and handlers
pages/ React pages (frontend projects)
assets/
css/index.css the entry stylesheet, auto-linked
public/ copied verbatim to the build root (llms.txt, robots, ...)
tests/ your test suites (Vitest by default)
stone.config.mjs build & rendering config (target, SSG routes)
tsconfig.json TypeScript config (stage-3 decorators set up for you)
.env local environment variables (never commit secrets)
.stone/ generated on build (safe to delete, never edit)
dist/ the build output (a single, self-contained artifact)#The two files that matter
Everything else is convention. Two files carry the meaning:
app/Application.ts: the manifest. The only place that names platforms (adapters) and sets app-wide options. This is the setup dimension made concrete.- your domain files (
app/Tasks.tsand friends): services and handlers. No structure is imposed; organise them however your domain wants.
#How your code is found
You never maintain a registry of handlers or services. At build time the CLI scans app/, and your decorators (or define* modules) register themselves onto the Blueprint. Add a file with a decorated class and it is part of the app; delete it and it is gone. No wiring file to keep in sync.
import { defineConfig } from '@stone-js/cli'
export default defineConfig({
rendering: 'ssg', // 'csr' | 'ssr' | 'ssg' (frontend)
ssg: { routes: ['/', '/about'] }
})