Documentation
Quick Start
Build your first Whitehall app in minutes.
Create a New Project
whitehall init myapp
cd myapp Your First Component
Open src/routes/+screen.wh and replace its contents with:
var count = 0
<Column class="gap-16 p-20">
<Text fontSize={24}>Count: {count}</Text>
<Button onClick={() => count++} text="Increment" />
</Column> Run It
whitehall run This builds your app, installs it on your connected Android device, and launches it.
Watch mode rebuilds automatically: whitehall build --watch
Understanding the Code
State
Declare a variable with var to make it reactive:
var count = 0 Behind the scenes, this becomes remember { mutableStateOf(0) } in Compose.
Components
Use HTML-like syntax for Compose components:
<Column class="gap-16">
<Text>Hello</Text>
</Column> Event Handlers
Arrow functions work everywhere:
<Button onClick={() => count++} /> Two-Way Binding
Use bind:value for form inputs:
var email = ""
<TextField bind:value={email} label="Email" />
<Text>You typed: {email}</Text> Conditional Rendering
Use @if to conditionally render components:
var showPanel = false
<Button onClick={() => showPanel = !showPanel} text="Toggle" />
@if (showPanel) {
<Card class="p-16">
<Text>Panel content</Text>
</Card>
} Lists
Use @for to iterate over arrays:
var items = ["Apple", "Banana", "Cherry"]
<LazyColumn class="gap-8">
@for (item in items) {
<Text>{item}</Text>
}
</LazyColumn> Styling with Tailwind Classes
Whitehall supports Tailwind-style utility classes for styling:
<Column class="p-16 gap-8 items-center bg-surface rounded-lg">
<Text class="text-2xl font-bold text-primary">Welcome</Text>
<Text class="text-sm text-secondary">Styled with Tailwind classes</Text>
</Column> Use class="" for static values and props for dynamic values. Props override classes when both are present.