Skip to content

Your first app

TL;DR. wun new app myapp scaffolds a counter screen and all four runtimes side-by-side. wun dev runs the server + shadow-cljs watch together; wun run ios and wun run android launch the native demos. Tap + in any of them, the others update on the next patch.

A new Wun app is a sibling of the wun monorepo — its deps.edn references the framework via :local/root paths to ../wun/wun-* by default, so the dev loop works without publishing.

Scaffold

  1. Clone the framework next to where your app will live.

    Terminal window
    cd ~/code
    git clone https://github.com/Holy-Coders/wun.git
  2. Generate the app.

    Terminal window
    wun new app myapp
    cd myapp
    npm install

    The CLI lays out:

    • Directorymyapp/
      • deps.edn server + cljs deps
      • shadow-cljs.edn
      • package.json
      • Directorypublic/
        • index.html
      • Directorysrc/myapp/
        • components.cljc your :myapp/* components
        • intents.cljc your morphs
        • screens.cljc starter screen
        • Directoryserver/
          • main.clj server entry point
        • Directoryweb/
          • main.cljs web entry point
      • Directoryios/ SwiftPM package for the macOS / iOS demo
        • …
      • Directoryandroid/ Gradle module for the Compose Desktop demo
        • …

    The starter screen has a counter with + and reset buttons.

  3. Run all three clients in parallel.

    Terminal window
    wun dev

    This starts the Clojure server on :8080 and shadow-cljs watch on :8081 together; one Ctrl-C stops both. Open http://localhost:8081 — your screen renders, the buttons fire intents, the page title reflects state.

    In other terminals:

    Terminal window
    wun run ios # macOS demo via swift run
    wun run android # Compose Desktop demo via gradle run

    All three clients connect to the same server and update in lock-step.

Add a screen

Terminal window
wun add screen myapp/profile

…creates src/myapp/profile.cljc with a starter defscreen. Edit the render fn, (:require [myapp.profile]) from src/myapp/server/main.clj and src/myapp/web/main.cljs so the side-effecting registration runs at startup.

Add a component

Terminal window
wun add component myapp/Card

Generates the defcomponent declaration plus iOS Swift + Android Kotlin renderers, and splices the registration into both example packs’ WunExample.swift / WunExample.kt. The CLI is idempotent — re-running detects existing files and skips them with a hint.

Add an intent

Terminal window
wun add intent myapp/log-in

Generates a defintent stub with a Malli :params schema and a placeholder morph. Wire it to a :wun/Button {:on-press ...} in a screen render fn.

Verify

Terminal window
wun status # per-component coverage matrix
wun doctor # env check

wun status shows which components have native renderers on each platform vs. which fall back to a server-rendered WebFrame. Aim for ✓ across the board for components users see often; WebFrame fallback is fine for niche / admin-only screens.

Next