Getting Started - Krate Docs
You're viewing an older version ().
Krate Docs

Install the Krate CLI, scaffold a project, and build your first interactive page.

#Getting Started

Active development

Krate is under active development and is not yet stable. APIs, generated output, and configuration may change between releases.

This guide walks you through installing the Krate CLI, scaffolding a project, and building your first page.

#Prerequisites

  • Node.js 20+ — for the npm CLI wrapper and running krate.config.ts
  • Go 1.26+ — only needed when building the compiler from source

The published CLI ships pre-built binaries for macOS, Linux and Windows, so you do not need Go to build a site.

#Install the CLI

npm install -g @krate/core
# or
pnpm add -g @krate/core

#Create a project

npx create-krate-app@latest my-app

create-krate-app scaffolds a complete project — including krate.config.ts, tsconfig.json, package.json, a landing page, a layout, and a 404 page. With no directory it prompts for a name.

Add a page:

// src/pages/index.tsx
export default function Home() {
  return <h1>Hello, World!</h1>;
}

#Build and run

krate dev       # dev server with hot reload on http://localhost:3000
krate build     # production build → dist/
krate serve     # preview the production build

#Your first interactive page

Krate's reactivity is built on signals. A signal is a getter/setter pair; reading a signal inside an effect subscribes that effect to it.

import { createSignal } from '@krate/runtime';

export default function Counter() {
  const [count, setCount] = createSignal(0);
  return (
    <div>
      <span>{count()}</span>
      <button onClick={() => setCount(c => c + 1)}>+</button>
    </div>
  );
}
  • count() reads the current value.
  • setCount(c => c + 1) writes a new value and notifies subscribers.
  • At build time the renderer extracts the initial value and emits static HTML.
  • At runtime the hydration bundle wires the button to update the <span>.

#Data fetching

Krate provides data through component tiers rather than page-level data functions:

// @server — evaluated at build time, HTML baked in
export default function ServerTime() {
  return <time>{new Date().toUTCString()}</time>;
}
// @runtime — evaluated per request, streamed via Suspense
export default function PriceTag({ price }) {
  return <span>{price}</span>;
}

Dynamic route pages receive their params as props via generateStaticParams. See Data Fetching for the full model.

#Layouts

A _layout.tsx file wraps every page in its directory (and subdirectories):

// src/pages/_layout.tsx
export default function Layout({ children }) {
  return (
    <div>
      <nav><a href="/">Home</a></nav>
      <main>{children}</main>
    </div>
  );
}

#Dynamic routes

Files named [param].tsx become dynamic segments:

// src/pages/video/[id].tsx → /video/abc123
export default function VideoPage({ params }) {
  return <h1>Video {params.id}</h1>;
}

#Built-in components

Built-in components (Head, Link, Icon, Image, Script, Style) are recognized by the compiler by name — no import needed:

export default function Page() {
  return (
    <>
      <Head>
        <title>My Page</title>
        <meta name="description" content="A cool page" />
      </Head>
      <Icon name="lucide:heart" />
      <Image src="/photo.jpg" width={800} alt="Photo" />
      <Link href="/about">About</Link>
    </>
  );
}

<Image> compiles to a WebP-first <picture>: lossy WebP variants generated at build time with original-format fallback, responsive srcset/sizes, lazy/eager loading, blur placeholders, and aspect-ratio-based CLS mitigation. <Link> renders an SPA-enabled <a> with prefetching, replace, scroll, hash scrolling, and aria-current for the active route.

#Using Go

Server and runtime components, and API routes, can also be written in Go. Install the Go toolchain, run krate go:init once for editor intellisense, then drop a .server.go / .runtime.go component under src/components or a route under src/api:

// src/components/badge.server.go
package components

import kr "github.com/kratejs/krate/packages/compiler/goext/krate"

type BadgeProps struct {
    Label string `json:"label"`
}

// krate:component server
func Badge(p BadgeProps) kr.Node {
    return kr.Span(kr.Class("badge"), kr.Text(p.Label))
}
import { Badge } from "@/components/badge.server.go";

export default function Page() {
  return <Badge label="Go!" />;
}

See Go Components and API Routes for the full guide.

#Next steps

Last updated: 2026-10-16

Contributors: Noinkin