Files
ritz/CLAUDE.md
T
Aaron Sinclair 635d466874 Implement Python → LLVM IR → WASM reactive framework
MAJOR ACHIEVEMENT: Full working reactive framework!

## What's Working

✅ Python → AST → Ritz IR → LLVM IR → WASM pipeline
✅ Reactive signals stored in WASM memory (@signal_name = global i32)
✅ Event handlers exported from WASM and callable from JS
✅ Clean runtime with RitzLoader and debug tools
✅ Two working examples: HelloWorld and HighFive counter

## Core Components

### Parser (ritz/parser.py)
- Uses Python's ast module to parse components
- Handles @component decorator, signals, event handlers
- Supports yield, with statements, f-strings, augmented assignment (+=)
- Clean syntax: from ritz.syntax import *

### LLVM IR Code Generator (ritz/llvm_codegen_signals.py)
- Generates LLVM IR directly (not C!)
- Signals as global variables in WASM memory
- Exports getter/setter functions for each signal
- Exports event handler functions for JS to call
- UTF-8 string handling

### Build System (ritz/build.py)
- Python → AST → IR → LLVM IR → clang --target=wasm32 → WASM
- Saves intermediate .ll files for inspection
- Debug symbols support (-g flag)

### Runtime (runtime/ritz-runtime.js)
- RitzRuntime class: DOM bridge for WASM
- RitzLoader class: Simplified component loading
- Debug bar with Ctrl+` toggle
- Signal updates trigger DOM updates

## Examples

### HelloWorld.py
Simple static content - renders <p>Hello World</p>

### HighFive.py
Reactive counter with:
- Signal in WASM memory (high_fives = signal(0))
- Event handler (increment function)
- DOM updates on signal change

## Test Coverage

- 4 parser tests (all passing)
- 4 LLVM codegen tests (all passing)
- 4 signal parsing tests (all passing)
- Code formatted with black and ruff

## Next Steps

- <script type="text/ritz"> in-browser compilation
- Better signal-to-DOM binding tracking
- More complex examples (TodoMVC, forms, lists)
- Playwright browser tests

---

This is a genuinely innovative framework: write Python, compile to WASM,
run with reactive signals in WASM memory. No virtual DOM, no transpilation,
just compiled Python with fine-grained reactivity.

🎉 Python → WASM → Reactive UI is REAL!
2025-11-15 01:50:40 -08:00

164 lines
6.1 KiB
Markdown

# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
Ritz is a WebAssembly UI framework with Python-like syntax that compiles to high-performance WASM while remaining executable in Python for debugging. The framework uses **valid Python syntax** that can execute in CPython for prototyping/debugging, but is designed to compile to WebAssembly for production.
**Current Status**: Python prototype stage. The WASM compilation pipeline is conceptual/architectural.
## Development Commands
### Running the Prototype
```bash
# Run example application showing various components
python3 example.py
# Run simple test
python3 test.py
# Test AST parser
python3 ast_parser.py
# View module system concept
python3 module_system.py
# View compilation pipeline concept
python3 compiler.py
# View debugging concept
python3 debug_concept.py
```
## Core Architecture
### Component Model
Components are defined using the `@component` decorator with Python generator syntax (yield-based):
```python
@component
def Counter():
count = signal(0) # Reactive state
def increment():
count += 1
with Div(class_='counter'): # Context managers for element nesting
yield H1('Counter') # Yield elements/strings/components
yield P(f'Count: {count}')
yield Button('Click me', onclick=increment)
```
Key patterns:
- **Generators**: Components are generator functions that yield children
- **Context managers**: Use `with Element():` for nested structures
- **Signals**: Reactive state via `signal(initial_value)`
- **Mixed content**: Can yield strings, elements, or other components
### File Structure
**Core Framework Files:**
- `framework.py` - Python prototype runtime (Signal, VNode, Element, component decorator)
- `ast_parser.py` - Parses Python components using Python's `ast` module to generate IR
- `compiler.py` - Complete compilation pipeline concept (Python → IR → LLVM → WASM)
- `module_system.py` - Progressive module loading architecture for code splitting
**Conceptual/Research:**
- `debug_concept.py` - Python-in-WASM debugging architecture (DWARF symbols, source maps)
- `RESEARCH.md` - Complete technical architecture and implementation roadmap
**Examples:**
- `example.py` - Demonstrates component syntax with various examples
- `test.py` - Simple test for debugging framework behavior
### Compilation Pipeline (Conceptual)
The planned compilation flow:
1. **Parser**: Uses Python's `ast` module to parse components (no custom parser needed!)
2. **IR Generation**: Transform Python AST → Ritz intermediate representation
3. **LLVM Codegen**: Ritz IR → LLVM IR
4. **WASM Output**: LLVM IR → WebAssembly with debug symbols (DWARF)
5. **Module Splitting**: Split into multiple WASM modules (bootstrap, core, features)
### Reactive System
**Signals** are the primitive reactive unit:
- Store a value and list of subscribers
- When value changes, notify all subscribers
- In Python prototype: simple Python class
- In WASM target: efficient memory layout with direct DOM node references
**Key insight**: No virtual DOM. Signals map directly to DOM nodes for updates.
### Module System Architecture
Apps split into multiple WASM modules for security and performance:
- `bootstrap.wasm` (~50KB) - Login only, no auth required, no business logic
- `app-core.wasm` (~200KB) - Main app, requires authentication
- `features/*.wasm` - Lazy-loaded feature modules
**Security benefit**: Unauthenticated users never receive app code containing API endpoints or business logic.
## Important Implementation Details
### AST Parsing
The framework uses **Python's own `ast` module** to parse components (not a custom parser). This provides:
- Zero parsing overhead
- Perfect Python compatibility
- Automatic syntax error messages
- Type hints support
See `ast_parser.py` for the `RitzASTTransformer` that converts Python AST to Ritz IR.
### VNode Structure
Internal representation during Python execution:
- `VNode(tag, props, children)` - Virtual DOM node
- `to_html()` - Render to HTML string
- `to_ir()` - Convert to intermediate representation for compilation
### Context Stack
`_context_stack` is a global list tracking nested `with Element():` blocks. The `@component` decorator manages this stack to build the component tree.
## Debugging Philosophy
**Revolutionary concept**: Debug Python code running in WASM, not JavaScript!
- DWARF debug symbols embedded in WASM
- Source maps linking WASM instructions → Python source lines
- Chrome DevTools can set breakpoints in Python files
- Inspect Python variables, not mangled JS
See `debug_concept.py` and RESEARCH.md sections on debugging.
## Design Principles
1. **Python-executable, WASM-compilable**: The same code runs in both environments
2. **Yield-based composition**: Natural Python syntax for building component trees
3. **Fine-grained reactivity**: Signals update DOM directly, no virtual DOM diffing
4. **Progressive loading**: Split code into secure, cacheable modules
5. **Developer experience**: Debug in Python, ship as WASM
## Performance Targets
Based on SolidJS/Leptos research:
- Bundle size: < 200KB compressed
- Startup time: < 500ms on slow 3G
- Update performance: Within 10% of vanilla JS
- Memory usage: 70% less than React
- DOM mutations: 99% fewer than virtual DOM frameworks
## When Modifying Code
1. **Python prototype** (`framework.py`): Currently functional, can be tested with Python
2. **Compilation pipeline** (`compiler.py`, `ast_parser.py`): Architectural/conceptual code that demonstrates intended design
3. **Module system** (`module_system.py`): Demonstrates progressive loading strategy
4. Components must be valid Python and use generator syntax with yield
5. All examples should run with `python3 example.py`
## Key Technical Decisions
- **Why yield?** Natural Python syntax, composable, clear execution order
- **Why compile vs interpret?** 10-100x performance, smaller bundle, type safety
- **Why LLVM?** Mature toolchain, excellent WASM backend, optimization passes
- **Why Python's ast module?** No custom parser needed, perfect compatibility