@@ -0,0 +1,73 @@
1+# CLAUDE.md
2+
3+Elm compiler forked to target LynxJS native UI instead of browser DOM.
4+
5+## Build
6+
7+```bash
8+cd compiler
9+stack build # build the compiler
10+stack install # install lynxjs-elm to ~/.local/bin
11+```
12+
13+Nix is required (provides zlib). Stack snapshot: lts-24.34, GHC 9.10.3.
14+
15+## Setup (kernel patching)
16+
17+Before compiling any Elm project, run the setup script to patch kernel JS files:
18+
19+```bash
20+bash scripts/setup.sh
21+```
22+
23+This copies standard Elm packages from `~/.elm` to `~/.lynxjs-elm` and applies LynxJS PAPI patches via `scripts/patch-virtualdom.py` and `scripts/patch-browser.py`.
24+
25+## Usage
26+
27+```bash
28+cd examples/counter
29+lynxjs-elm make src/Main.elm # → main.lynx.bundle (default)
30+lynxjs-elm make src/Main.elm --output=foo.lynx.bundle # → foo.lynx.bundle
31+lynxjs-elm make src/Main.elm --output=elm.js # → raw JS only
32+lynxjs-elm dev src/Main.elm # dev server with watch
33+```
34+
35+Don't set `ELM_HOME` — the compiler already defaults to `~/.lynxjs-elm`.
36+
37+## Project layout
38+
39+```
40+compiler/ # This jj repo — the forked Elm compiler (Haskell)
41+ compiler/src/ # Core compiler: parser, type checker, code gen, AST
42+ builder/src/ # Build system, package management, dependency resolution
43+ terminal/src/ # CLI commands: Make.hs, Dev.hs, Init.hs, Install.hs, etc.
44+ reactor/ # Dev server (elm reactor)
45+ worker/ # Compilation worker
46+browser/ # Patched elm/browser package (separate jj repo)
47+virtual-dom/ # Patched elm/virtual-dom package (separate jj repo)
48+http/ # Patched elm/http package (separate jj repo)
49+ui/ # lynx/ui — LynxJS-specific Elm package (separate jj repo)
50+examples/ # Demo apps (counter, hello-world, http-example)
51+scripts/ # Kernel patching and setup scripts
52+```
53+
54+Each subdirectory (compiler, browser, virtual-dom, http, ui) is its own jj repo.
55+
56+## Kernel JS rules
57+
58+The Elm kernel JS parser (`compiler/src/Elm/Kernel.hs`) has strict constraints:
59+
60+- `__` prefix in kernel JS is parsed as a kernel module reference. Use `'_' + '_'` string concatenation for LynxJS PAPIs (e.g., `__CreateView`).
61+- Never rewrite kernel JS from scratch — always patch from the original in `~/.elm/` using the Python scripts. The parser is extremely sensitive to byte structure.
62+- Stick to ASCII in kernel JS files.
63+- After any kernel change, rerun `scripts/setup.sh` and test compilation.
64+
65+## Bundler rules
66+
67+- Use raw rspack, NOT rspeedy/ReactLynx
68+- `@lynx-js/template-webpack-plugin` must be version `0.6.4` exactly
69+- `package.json` must have `"type": "module"`
70+- Elm init must happen inside `renderPage()`, not at module level
71+- `globalThis['runWorklet']` must be defined for events to work
72+- Elements use `__CreateView(pageId)` / `__CreateText(pageId)` (not `__CreateElement`)
73+- Events use `__AddEvent(el, 'catchEvent', name, { type: 'worklet', value: fn })`