Frontend Options
Andurel v2 has one UI layer: Inertia v3 with React, Vue or Svelte over Vite. The Go backend owns routing, authorization, validation and data; the frontend owns page rendering and local interaction.
Templ is not a page layer in v2. It remains for email templates and the single Inertia root document, resources/root.templ.
Choose the adapter and package manager
A new project is Inertia by default. Pick the adapter and JavaScript package manager when you scaffold:
1andurel new orbit # Inertia React with pnpm (the default)
2andurel new orbit --ui react/pnpm
3andurel new orbit --ui vue/bun
4andurel new orbit --ui svelte/npm
The adapter is react, vue or svelte. The package manager is pnpm, bun or npm. The choice is stored in andurel.toml and drives dependency installation and the production build.
The Go side is the same in every case. The adapter changes resources/js, the Vite plugins and dependencies, and the entry point in config/inertia.go.
How a page is served
A handler names a page component and passes serializable props:
1return h.renderer.Page(ctx, "Products/Index", inertia.Props{
2 "items": toProductResources(products),
3 "totalPages": totalPages,
4}).Render()
The component name maps to resources/js/Pages/Products/Index.tsx (or .vue / .svelte):
1import Layout from '@/Layouts/Layout'
2
3type ProductResource = {
4 id: string
5 name: string
6}
7
8type Props = {
9 items: ProductResource[]
10 totalPages: number
11}
12
13export default function Index({ items, totalPages }: Props) {
14 return (
15 <Layout>
16 <h1>Products</h1>
17 <p>{items.length} products across {totalPages} pages</p>
18 </Layout>
19 )
20}
The first visit renders the root document with the page object embedded and loads Vite. Later visits return page JSON and the official Inertia adapter swaps components.
Keep the data contract deliberate. Props are JSON: give response structs stable JSON tags and never pass database models or generated SQL rows to a page.
TypeScript contracts
Two generated files keep the browser boundary honest:
resources/js/routes.tscomes from the route manifest. Refresh it withandurel sync routesand importroutesinstead of hard-coding URLs.resources/js/types/payloads.tscomes from named request payload structs decoded by handlers, plus handler-owned structs passed toinertia.FromStruct. Refresh it withandurel sync payloadsand import the form and page types it contains.
Props passed as a literal inertia.Props map are not generated, and a prop struct imported from another package is not followed (the sync fails rather than guessing). Type those in the component next to the handler that sends them.
Assets and SSR
andurel run starts the Vite dev server and proxies development assets. andurel build compiles Tailwind, the Vite client bundle, the SSR bundle and the Go binary.
SSR is opt-in per page:
1return h.renderer.Page(ctx, "Products/Index", props).SSR().Render()
In development the render goes through the Vite dev server, so start the app with andurel run. In production, cmd/ssr owns the Node renderer and the app reaches it at INERTIA_SSR_URL. Managed SSR requires Node.js 22 or newer. config/inertia.go defaults INERTIA_SSR_FAIL_FAST to true (the shipped .env.example turns it off for local development), so when fail-fast is on, an unavailable renderer fails the page rather than silently degrading.
What v2 does not offer
- No Templ page layer, so no Datastar signals, fragments or server-sent-event patches. Pages and interactions are Inertia components and ordinary HTTP requests.
- No per-route choice between Templ and Inertia. The project has one UI adapter.
- No frontend code generators. Handlers, pages and route values are written from the reference patterns;
andurel syncrefreshes derived helpers, andandurel generateonly creates migrations. - No mixed server-rendered marketing pages beside an Inertia app. A public page is still an Inertia page, or a plain
anduin.HTML/anduin.JSONendpoint when it is not page-shaped.
For JSON endpoints, register a normal route without routing.InertiaRoute() and return anduin.JSON(ctx, status, value). For the protocol details, see Inertia.
Moving from the Templ stack
A v1 Templ and Datastar UI has to be rebuilt as Inertia pages: typed component calls become a JSON props contract, and local interactions become frontend state or ordinary requests. The Go domains and services survive the move. See Moving to v2.