ajo

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.

Terminal
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.3

Connect Vite and JSX

Set "type": "module" in package.json. Kit discovers routes and handles the server and client build.

vite.config.ts
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.

tsconfig.json
{
  "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.

index.html
<!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.

src/page.tsx
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.

Terminal
pnpm exec kit dev

# In another terminal, or after stopping dev:
pnpm exec kit build