Start here
Your first route
Create an Ajo Kit application, run it locally and prepare it for the engine.
Start with a project
Use Node 22.18 or newer for development. Create an empty directory and add the UI library, framework and build tools. These tools build the App; the Ajo Engine runs it in production.
mkdir hello-ajo
cd hello-ajo
pnpm init
pnpm add ajo@0.1.35 ajo-kit@0.3.2
pnpm add -D vite@8.0.16 typescript@6.0.3 @types/node@25.9.3Connect Vite and JSX
Set "type": "module" in package.json. Kit discovers routes and handles the server and client build.
import { defineConfig } from 'vite'
import { kit } from 'ajo-kit/vite'
export default defineConfig({
plugins: [...kit()],
optimizeDeps: { exclude: ['ajo-kit/client'] },
})Add the TypeScript configuration
The JSX settings tell Vite 8 and TypeScript to use Ajo. Import the framework from its public ajo-kit package.
{
"compilerOptions": {
"target": "ESNext",
"lib": ["ESNext", "DOM"],
"module": "ESNext",
"moduleResolution": "bundler",
"jsx": "react-jsx",
"jsxImportSource": "ajo",
"strict": true,
"skipLibCheck": true,
"noEmit": true
}
}Give the page a document
Kit fills the head, route data and rendered HTML slots. The Vite plugin provides the client entry.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- ssr:head -->
</head>
<body>
<!-- ssr:data -->
<div id="root"><!-- ssr:root --></div>
<script src="/src/client" type="module"></script>
</body>
</html>Write a page
Create src/page.tsx. Its location makes it the / route. A plain function is enough when the view has no local state.
export default () => (
<main>
<h1>Hello, Ajo.</h1>
<p>Your first route is ready.</p>
</main>
)Run and build
The dev command starts a local Vite application. Build writes the server graph, client assets and compiler descriptor to .ajo/. Without a compiler, it prints the next command to run.
pnpm exec kit dev
# In another terminal, or after stopping dev:
pnpm exec kit build