Documentation

Getting started

Prerequisites

  • macOS on Apple Silicon with Xcode (iOS Simulator runtime installed)
  • Homebrew

Install

brew tap franckverrot/walnut
brew install walnut

This installs the CLI, stdlib, iOS runtime, and docs. Details: homebrew.md.

walnut version

Create an app

walnut new HelloApp
cd HelloApp

This scaffolds:

HelloApp/
├── walnut.toml            # project manifest
├── src/
│   └── Main.walnut        # starter counter with glass buttons
├── tests/
│   └── Smoke.walnut       # host JIT smoke tests (`walnut test`)
└── ios/
    ├── project.yml        # native shell project
    └── Sources/
        └── AppDelegate.swift

walnut new also installs agent skills (daily workflow, live debug + dispatch, host tests, language pitfalls, diagnostics). Open the app folder in your coding agent so it picks them up.

Compiler errors use rich WN#### diagnostics (snippet + Hint). See diagnostics.md.

AppDelegate.swift is the thin native host:

window.rootViewController = WalnutApp.bootstrapOrShowError()

WalnutApp runs the TEA loop and calls into your compiled Walnut program.

Run it

walnut check         # static typecheck
walnut test          # host JIT unit tests (no Simulator)
walnut simulator     # compile → Simulator
walnut debug         # TEA console: p model, dispatch Msg, time travel

Override the device with --device "iPhone 17 Pro". For a physical phone, use walnut device (device.md). To produce the .app without launching, use walnut build.

Iterate

  1. Edit src/Main.walnut.
  2. walnut check for fast typechecking.
  3. walnut simulator (or walnut simulator --watch for hot reload).

Explore types in the REPL

walnut repl
walnut> 2 ^ 10
1024 : Float

:type <expr> typechecks without running. Full notes: jit.md.

Run a pure Walnut file as a script

main does not have to be an app:

-- fizzbuzz.walnut
module FizzBuzz exposing (main)

fizz n =
    if modBy 15 n == 0 then "FizzBuzz"
    else if modBy 3 n == 0 then "Fizz"
    else if modBy 5 n == 0 then "Buzz"
    else String.fromInt n

main =
    List.range 1 15
        |> List.map fizz
        |> String.join " "
walnut run fizzbuzz.walnut

Where to go next