brust 2.0.0-alpha.5
Cookbook / Hello world

Hello world

The smallest app: one page, one route. Then a route with a path param and a loader.

1Write a page

A page is a plain React component. This one has no state and no handlers, so the compiler marks it static: rendered once, served as HTML.

pages/HelloPage.tsx
export default function HelloPage() {
  return (
    <section>
      <h1>Hello, Pikachu</h1>
      <p>Served by Rust. No client JavaScript.</p>
    </section>
  )
}
routes.tsx
import { defineRoutes } from '@brust/core/routes'
import HelloPage from './pages/HelloPage'

export const routes = defineRoutes([{ path: '/', Component: HelloPage }])

2Run it

bun run dev builds and starts the server (the Quickstart shows its output). Then ask for the page:

~/my-app
$ curl -i http://127.0.0.1:1337/
HTTP/1.1 200 OK
content-type: text/html; charset=utf-8
x-powered-by: brust/2.0.0-alpha.3
content-length: 87

<section><h1>Hello, Pikachu</h1><p>Served by Rust. No client JavaScript.</p></section>

3Add a param route

A path segment in braces becomes a param. The loader reads it, looks the Pokémon up, and returns the props the page renders. A name it does not know returns notFound(...), which answers 404.

lib/loaders.ts
import { type LoaderCtx, notFound, type Verdict } from '@brust/core/routes'
import { byName } from './pokemon'

export async function pokemonLoader({ params }: LoaderCtx<{ name: string }>): Promise<{ name: string; id: number; types: string } | Verdict> {
  const p = byName(params.name ?? '')
  if (!p) return notFound({ name: params.name ?? '', id: 0, types: '' })
  return { name: p.name, id: p.id, types: p.types.join(' / ') }
}
routes.tsx
{ path: '/pokemon/{name}', Component: PokemonPage, loader: pokemonLoader },
pages/PokemonPage.tsx
export default function PokemonPage({ name, id, types }: { name: string; id: number; types: string }) {
  return (
    <section>
      <h1>{name}</h1>
      <p>#{id} · {types}</p>
    </section>
  )
}
~/my-app
$ curl -s http://127.0.0.1:1337/pokemon/pikachu
<section><h1>pikachu</h1><p>#25 · electric</p></section>
$ curl -si http://127.0.0.1:1337/pokemon/missingno | head -1
HTTP/1.1 404 Not Found
Note

Loaders have their own page: Loaders and params. For the catch-all 404 document, see Static 404 page.