Getting started
For a quicker start, see quick-start. For detailed toolchain setup, see installation.
Prerequisites
| Tool | Version | Why |
|---|---|---|
| elan + Lean | leanprover/lean4:v4.15.0 (pinned in lean-toolchain) | compiles the framework and checks every theorem |
| Lake | ships with the toolchain | build driver and target runner |
| Node.js | v20+ (developed on v26) | the replayers, coverage gates and fuzz-parity harness |
impl-foundation | checked out as a sibling directory | lakefile.lean does require «foundation» from ".." / "impl-foundation" |
Encapp resolves foundation by path, so the two repositories must sit side by side:
dev/
├── impl-encapp/
└── impl-foundation/
1. Build the framework
cd impl-encapp
~/.elan/bin/lake buildThis does more than compile. Every theorem in the repository is checked here — the
refinement proof, the replay laws, the bridge to Foundation.Layer.mono, and every
workflow's native_decide. A red build is a failed proof, not just a failed compile.
2. Emit an app
The hello example compiles to all three targets in one command:
~/.elan/bin/lake exe helloappOutput:
dist/index.html the web SPA, self-contained (no build step, no framework dependency)
dist/native/app.cjs the React Native module
dist/desktop/main.cjs the Electron main process
dist/desktop/preload.cjs the Electron preload bridge
dist/desktop/package.json the Electron package manifest
Open dist/index.html in a browser — it needs no server, no bundler and no node_modules.
There are four executables declared in lakefile.lean:
| Target | Root | Emits |
|---|---|---|
helloapp | HelloApp.lean | the full hello app, all three platforms |
emulator | EmuGenMain.lean | the ENC emulator — phone shell plus its apps, authored as RView data |
encapp | Main.lean | the minimal Spec counter through Codegen.emit |
hellocheck | HelloCheck.lean | hello's final state as JSON, for the compatibility diff |
3. Run the gates
node test/hello-matrix.mjsThis is the framework's own end-to-end gate, and it is deliberately broad:
lake build Encapp.Examples.HelloWorkflow— the proofs must be current before they are audited.- Axiom audit —
lake buildonly warns onsorry, so a keystone could rot to unsound and still build green.axiom-audit.mjspins each keystone's axiom set with#print axiomsand fails onsorryAxor any axiom outside the accepted set.Foundation.Layer.monois pinned to exactly zero axioms. - Coverage gates —
page-coverage.mjs,handler-coverage.mjs,nav-integrity.mjs. These are app-generic: the same tools drive the flagship app. lake exe helloapp— emit the artifacts under test.- Native parity — core-identity (one step engine, web ≡ native), locatability, input-sync, and seeded differential fuzzing.
- Replay — the emitted corpus is executed on the happy-dom and headless-Chromium tiers.
See Testing and coverage gates for what each gate catches and why it exists.
4. Write your own app
The shortest complete example is Encapp/Examples/Hello.lean — 177 lines
covering three routes, an identity handshake, a composer and two tables. Start by copying its
shape:
import Encapp
open Encapp Encapp.ViewDsl
def myApp : ReflApp Unit where
init := { scalars := [("path", .str "/home")], tables := [] }
pages := [("/home", box "padding:24px" [ txt "font-size:20px" "Hello" ])]
handlers := [ ⟨"nav", [ .setInput "path" ]⟩ ]Then add a main that calls AppGen.emit, and register it in lakefile.lean as a
lean_exe. The full walkthrough is in The app model.
Where things live
| Path | What |
|---|---|
Encapp/ | the framework — 2,472 Lean lines across 16 modules |
Encapp/Examples/ | Counter.lean, Hello.lean, HelloWorkflow.lean |
test/ | replayers, coverage gates, axiom audit, fuzz-parity |
dist/ | emitted artifacts (git-ignored output) |
docs/ | this site |
docs-internal/ | the earlier long-form notes and platform progress logs |
Recap
- Encapp requires Lean 4.15.0, Lake, Node.js v20+, and impl-foundation as a sibling directory
lake buildproves all theorems and audits axioms; a red build means a failed proof- One command (
lake exe helloapp) emits to three platforms without per-platform build steps - Test gates validate proofs, coverage, replay across web/native/desktop tiers, and native parity
- Apps start from the hello example (177 lines), extended through
AppGen.emitand amainfunction
Next steps
- The app model — How ReflApp, pages, handlers, and tables fit together
- Testing and coverage gates — What each gate catches and why it exists