Your first app
TL;DR.
wun new app myappscaffolds a counter screen and all four runtimes side-by-side.wun devruns the server + shadow-cljs watch together;wun run iosandwun run androidlaunch 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
-
Clone the framework next to where your app will live.
Terminal window cd ~/codegit clone https://github.com/Holy-Coders/wun.git -
Generate the app.
Terminal window wun new app myappcd myappnpm installThe 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
+andresetbuttons. -
Run all three clients in parallel.
Terminal window wun devThis starts the Clojure server on
:8080and shadow-cljs watch on:8081together; 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 runwun run android # Compose Desktop demo via gradle runAll three clients connect to the same server and update in lock-step.
Add a screen
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
wun add component myapp/CardGenerates 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
wun add intent myapp/log-inGenerates 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
wun status # per-component coverage matrixwun doctor # env checkwun 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.