A Rust/WASM web framework with its own markup language. Write declarative UI in Markout, get reactive DOM with no build step, no virtual DOM diffing overhead, and no component trees.
@card padding:24
| Welcome back, {label:user animate:fade}
| Email {input:email validate:required,email col-6}
| Password {password:pass validate:required,min:8 col-6}
| {button:login "Sign In" primary} {spacer:end} {link:forgot "Forgot password?" ghost}
@end card
constapp=Outconceive.from_markout(markout);app.mount('#app');app.on('login',()=>{if(app.validate()){app.fetch('/api/login',{email: app.get('email'),pass: app.get('pass')});}});app.computed('user',()=>app.get('email').split('@')[0]||'stranger');app.persist('email');app.theme('dark');That's a validated login form with computed display name, dark theme, persistent email, and async submit. No JSX, no transpiler, no node_modules.
17 components — input, password, button, checkbox, radio, select, textarea, label, link, image, divider, spacer, pill, badge, progress bar, sparkline, custom
11 containers — @card, @form, @section, @nav, @header, @footer, @main, @aside, @columns, @editor, @parametric
Parametric layout — @parametric container where components position themselves via named constraints (center-x:title, gap-y:1rem:search, left:start right:end). Rust solver computes absolute positions from a dependency graph — no runtime DOM measurement
Rich text editor — @editor bold italic code heading list embeds a WASM-powered editor with opt-in features. The feature list is a contract: undeclared formatting is stripped from pasted content
Reactive state — set() / get() / computed() / effect() / memo() with automatic dirty tracking and incremental re-render
Routing — hash-based with declarative route:/path links and route-active CSS class
Lists — @each items / @end each with auto-scoped state per item
Form validation — validate:required,email,min:3,max:50,pattern:regex with custom validators
Data fetching — fetch:/api/endpoint with automatic loading/error state management
Theming — 3 built-in themes (light, dark, nord), 30+ CSS custom properties, custom themes via JS
Responsive grid — 12-column with col-6, col-3[5] (custom denominators), and 4 breakpoints (sm:col-6, md:col-4, lg:col-3, xl:col-2)
8 animations — fade, slide, slide-up, scale, bounce, pulse, shake, glow — declarative or programmatic
SSR + hydration — Rust renders HTML strings, JS hydrates without re-render
Templates — @define / @use with scoped state for reusable blocks
Persistence — app.persist('key') auto-saves/restores from localStorage
Multi-mount — independent instances as islands, connected via pub/sub event bus
Popovers — popover:"Tooltip text" on any component, pure CSS
Visual IDE — toolbar, click-to-select, property panel, live Markout source editor
Every other framework models UI as a tree: components own children, identity requires generated keys, structural changes cascade through the hierarchy.
Outconceive uses parallel strings. Each UI row is four equal-length strings:
content: "Username ________ Login "
components: "LLLLLLLLLLIIIIIIIIIIBBBBBB"
state_keys: "__________username__submit"
styles: " pppppp"
A component's identity is its line number and character offset — trivially computable, zero maintenance. No reconciliation, no key diffing, no tree walks. State updates re-render only the affected lines: O(1).
<scripttype="module">importinit,{OutconceiveApp}from'./pkg/outconceive.js';awaitinit();constapp=Outconceive.from_markout(OutconceiveApp,` @card padding:16 | Count: {label:count} | {button:inc "+" primary} {button:dec "-" danger} @end card `);app.mount('#app');app.set('count','0');app.on('inc',()=>app.set('count',String(+app.get('count')+1)));app.on('dec',()=>app.set('count',String(+app.get('count')-1)));</script>| Layer | Technology | Size |
|---|---|---|
| Core | Rust → WASM | ~230KB |
| Runtime | Vanilla JS (no dependencies) | ~20KB |
| Styles | CSS custom properties | ~12KB |
| Docs | VitePress | 20 pages |
138 Rust tests. No build step required. No npm dependencies at runtime.
# Rust tests
cargo test# WASM build
wasm-pack build --target web
# Dev server
node serve.js
# → http://localhost:909615 demo pages covering login forms, todo lists, price calculators, form validation, data fetching, inter-instance messaging, persistence, theming, responsive layouts, animations, SSR + hydration, templates, widgets, and the visual IDE.
Full documentation site built with VitePress — guides, API reference, and architecture deep dives.
MIT