Why Limen
Make fewer architectures legal.
React and Angular are mature, capable frameworks. Limen is aimed at a different problem. It does not add more abstraction or more APIs. It makes application authority, effects, outcomes, and browser interaction explicit enough that compilers and repository checks can reject whole categories of mistakes.
React and Angular provide powerful ways to build applications. Limen deliberately narrows the number of legal architectural choices so important mistakes can be rejected by types, contracts, conformance tests, and repository guardrails.
This page describes design intent and structural consequences. Each claim below is labelled as implemented today or as accepted architecture that is still being built. Measured comparisons with React or Angular do not exist yet — see Evidence.
01 · Optimization target
Different questions, not a better score.
React and Angular make the right thing convenient. Limen’s goal is to make the wrong thing structurally difficult.
| Question | React | Angular | Limen |
|---|---|---|---|
| Primary optimization | A flexible component model and the freedom to assemble an architecture from a broad ecosystem | An integrated framework: components, dependency injection, routing, forms, and tooling that fit together | System legibility: one explicit owner of application meaning and a small set of legal places for behavior to live |
| Where application architecture comes from | Team choice, assembled from framework facilities and libraries | Framework conventions, with room for team choice | The boundary itself: meaning in the engine, mechanism in the browser, data between them |
| How architectural mistakes are caught | Review, linting, conventions, and the team’s own discipline | Framework structure, strong tooling, template type-checking, and review | Types, the protocol, architecture checks, and repository guardrails — some implemented today, more accepted and in progress |
| How capability grows | Add libraries | Add framework features and libraries | Add optional capability packs, engine libraries, or hosts — without growing the Core an application must learn |
Both frameworks can be used to build well-structured applications, and many teams do. The difference is where the structure comes from: in React and Angular it is largely a design choice made inside a flexible system; in Limen it is the thing the system is built around.
02 · Authority boundary
Meaning and browser authority never sit in the same code.
The code that knows what something means cannot directly perform browser authority, and the code with browser authority cannot know what the application means.
The DOM is output, never application truth. Effects are explicit data. Browser APIs are capabilities performed by the browser side. Application meaning belongs to the engine.
Implemented today for HTTP, storage, clipboard write, and navigation. The language-neutral WASM contract in step 04 is accepted architecture; today the contract is the TypeScript protocol in src/protocol.ts.
- 01Application engine holds authoritative state.
- 02Legal transition decides what may happen now.
- 03Typed capability request describes an effect as data.
- 04Language-neutral WASM contract carries it across the boundary.
- 05Browser provider performs it and classifies the outcome.
- 06Browser API — the only place the browser is actually touched.
03 · Illegal states and typed outcomes
Name every state, including “we do not know”.
A closed set of states leaves no room for an impossible combination of flags.
type Resource =
| NotRequested
| Loading
| Ready
| Refreshing
| Failed
// Illustrative model. A shared async-resource
// engine library is accepted work (#15, LCP-009).
src/protocol.ts)type EffectOutcome =
| { kind: "Success"; status; body }
| { kind: "Failure"; reason: "network" | "aborted" | "invalid-response" | "too-large" }
| { kind: "Cancelled" }
| { kind: "OutcomeUnknown"; reason: "timeout-after-dispatch" | "connection-lost" };
// OutcomeUnknown is not Failure: a timed-out
// write may already have been applied.
React and Angular applications can be modelled this way too, and good ones often are. Nothing in either framework prevents strong state modelling. The Limen claim is narrower: it makes explicit state, capabilities, outcomes, and authority boundaries foundational — part of the protocol every engine speaks and of the tooling that checks it — rather than a practice a team chooses to adopt.
Unknown outcomes remain unknown until reconciled. On this site’s release demo, a timeout after dispatch becomes reconciliation-required state with no retry button until authoritative evidence arrives.
04 · Agent constraint
Better instructions are useful. Mechanical constraints are stronger.
Autonomous agents infer and continue. A rule that only lives in a prompt can be missed; a rule that fails the build cannot.
Instruction
“Please don’t keep application state in browser JavaScript.”
Depends on the agent reading, retaining, and applying it on every change.
Mechanical rule
The build fails because browser-side code crossed the authority boundary.
Holds whether or not the instruction was read.
| Guardrail | What it rejects | Status |
|---|---|---|
| Engine purity check | Browser APIs, any, or dynamic in the TypeScript reference engine; JS interop or I/O in this site’s F# engine | Implemented — scripts/check-architecture.ts, run by npm test and CI |
| Compiler-visible closed types | An unhandled union case in this site’s F# engine and federation modules (warnings are errors) | Implemented for the F# reference engine |
| Work-item attribution | Meaningful changes with no recorded work item | Implemented — ros validate in CI |
| One neutral contract source | Two hand-maintained copies of the wire protocol drifting apart | Accepted, in progress — #15, #52 |
| Generated, read-only bindings | Hand edits to, or stale copies of, generated protocol code | Accepted, in progress — #52 |
| Restricted TypeScript | any, suppression directives, eval, and untyped escape hatches in handwritten boundary code | Partial — engine-side ban today; the full subset is #54 |
| Dependency and path-scope checks | Core importing optional capabilities or application code; a change outside its work item’s declared scope | Accepted, in progress — #53 |
| Shared conformance vectors | A guest engine that encodes or decodes the contract differently from the others | Accepted, in progress — #17, #32 |
| Non-weakenable guardrails | Feature work that disables or loosens the check blocking it | Accepted rule (#51); enforced today by review and work-item scope, not yet by a check |
Limen is designed to reduce the legal implementation search space available to an agent. That is an architectural objective. Whether it measurably improves agent accuracy, defect rates, or token use has not been tested.
05 · Language-neutral WebAssembly
Limen is a WebAssembly boundary, not an F# framework.
F# is our reference implementation. The contract is language-neutral.
language-neutral Limen contract
│
┌─────────────┼─────────────┐
▼ ▼ ▼
F# WASM C# WASM Rust WASM
│ │ │
└─────────────┼─────────────┘
▼
browser host
(TypeScript today)
│
▼
browser APIs
No guest language is canonical. Each guest should receive the strongest closed-type model natural to it, generated from the same source, and pass the same conformance vectors.
- JSON is the current baseline wire format.
- WebAssembly Component Model / WIT may become an additional backend; Limen does not require it.
- TypeScript is the browser host language today — mechanism, not semantic authority.
- Echelon Foundry prefers F# for its own engines. That preference is not part of the protocol.
| Language | Role | Compile-time enforcement | Status on main |
|---|---|---|---|
| F# | WASM application engine | Discriminated unions and exhaustive pattern matching | Running — this site’s engine and the two-module federation proof. Its protocol types are a handwritten mirror today. |
| Rust | WASM application engine | Enums, Result / Option, exhaustive matching | Accepted target — #17, #55 |
| C# | WASM application engine | Generated closed representations, nullable analysis, analyzers or source generators where the compiler alone is not enough | Accepted target — #17, #55. C# on this site today is only the [JSExport] marshalling shim. |
| TypeScript | Browser host | Discriminated wire types; generated from the neutral contract once #52 lands | Running as the host and kernel; protocol types handwritten today |
06 · Effects are inspectable data
An effect you can read is an effect you can test.
Because the engine returns requests instead of performing them, everything below is ordinary data handling.
Implemented
Deterministic engine tests
Given state and evidence, assert the next state and the effects requested — no browser, no mocks of fetch.
Implemented
Correlation and stale-result rejection
Every request carries a correlation ID, so the engine can recognise a late result for an older request and discard it.
Implemented
Cancellation
The engine lists correlation IDs to cancel; the kernel aborts those HTTP requests and reports Cancelled.
Implemented
Explicit unknown outcomes
OutcomeUnknown stays distinct from failure and becomes a reconciliation obligation, not a blind retry.
Partial
Fake hosts
Tests drive the kernel with a scripted transport today. A generic fake host and conformance suite is accepted work (LCP-031).
Accepted, not built
Trace and replay
Messages are serializable, so a recorded session can in principle be replayed. Runtime trace/replay tooling is accepted work (LCP-029).
07 · A small cognitive Core
Capability reach does not require Core accumulation.
Minimize the concepts an agent must understand, not the outcomes Limen can support.
| If it is… | It belongs in… |
|---|---|
| Meaning | The engine |
| Browser mechanism | A capability |
| Appearance | CSS |
| Structure | HTML |
| Opaque complex surface | A governed adapter |
| Alternate execution or delivery | An optional host or renderer |
| Development verification | Tooling and conformance |
An application imports and learns only the capabilities it uses. Engine libraries, capability packs, adapters, optional hosts, Forma interaction patterns, and tooling stay distinct from Core, so broader reach does not make the minimal application harder to understand. Today’s Core carries four capabilities — HTTP, storage, clipboard write, and navigation. The wider placement model is accepted architecture from the capability parity specification (#15).
08 · Honest trade-offs
Where React and Angular are stronger today.
These are real advantages, and for many projects they should decide the question.
Mature ecosystems
Years of production use, extensive community knowledge, and answers to most problems already written down.
Component and UI libraries
Design systems, data grids, editors, and charting ready to use. Limen has none of its own yet.
Hiring and familiarity
Many developers already know React or Angular. Limen requires learning a different model.
Framework tooling
Angular’s integrated CLI, dependency injection, routing, forms, and template type-checking; React’s developer tools and wide tool support.
Integrations and rendering
Established server rendering, hydration, accessibility tooling, and third-party integrations. Limen’s equivalents are accepted work, not shipped features.
Time to first screen
For a conventional application, a familiar framework and its scaffolding usually gets a first screen working sooner.
Limen is aimed at systems where enforceable correctness, explicit authority, language-neutral WASM, agent legibility, and long-term architectural integrity are worth giving up some ecosystem convenience.
That is a statement of positioning, not a measured ranking. If ecosystem breadth or delivery speed on a conventional application matters most to you, React or Angular is likely the better fit today.
09 · Evidence
What is proven, and what is still an argument.
This site keeps four kinds of claim apart, so a persuasive sentence cannot pass as a result.
- 01Enforced — a build or check fails if the property is false.
- 02Demonstrated — a real implementation shows it can be done, such as this site’s F# WebAssembly engine.
- 03Structurally implied — follows from the architecture when its rules hold.
- 04Still requires controlled comparison — speed, defects, agent accuracy, tokens, cost, and size compared with React or Angular.