Core Docs Data flow, component interaction, and internal architecture.
Eleva’s design emphasizes clarity, modularity, performance, and agent-readiness (AX).
Components are plain JavaScript objects that describe a UI segment:
template function - Returns HTML with interpolation placeholderssetup() function - Initializes state using reactive signals (optional)style function - Component CSS (optional)children object - Nested components (optional)Signals are reactive data holders that notify watchers when their values change, triggering re-renders of the affected UI.
Evaluates expressions in @events and :props attributes against the component context, enabling event binding and prop passing.
Compares the new HTML structure with the current DOM and patches only the parts that have changed, ensuring high performance without virtual DOM overhead.
Implements a publish-subscribe pattern to allow components to communicate by emitting and listening to custom events.
app.component()app.mount() creates a context (props, lifecycle hooks, emitter) and executes setup() to create reactive state${}) interpolate values directly@events and :props expressions@click) are bound during rendering[Component Registration]
│
▼
[Mounting & Context Creation]
│
▼
[setup() Execution → Creates Signals]
│
▼
[Template Function Produces HTML]
│
▼
onBeforeMount
│
▼
[Renderer: Diff → Patch DOM]
│
▼
[Process @events & :props]
│
▼
[Inject Styles]
│
▼
[Mount Child Components]
│
▼
onMount
│
▼
┌────────────────────────────────────────────┐
│ ↺ REACTIVE CYCLE │
├────────────────────────────────────────────┤
│ │
│ [Idle: Waiting for Signal Change] ◄───┐ │
│ │ │ │
│ ▼ │ │
│ [User Event / Signal Change / Emit] │ │
│ │ │ │
│ ▼ │ │
│ [queueMicrotask Batches Updates] │ │
│ │ │ │
│ ▼ │ │
│ [Template Re-evaluation] │ │
│ │ │ │
│ ▼ │ │
│ onBeforeUpdate │ │
│ │ │ │
│ ▼ │ │
│ [Renderer: Diff → Patch DOM] │ │
│ │ │ │
│ ▼ │ │
│ [Process @events & :props] │ │
│ │ │ │
│ ▼ │ │
│ onUpdate ────────────────────────┘ │
│ │
└────────────────────────────────────────────┘
For contributors or developers seeking a deeper understanding:
[Component Registration]
│
▼
[Mounting & Context Creation]
• props passed to context
• emitter reference (shared instance)
• signal factory function
│
▼
[setup() Execution]
• Creates signals via factory
• Returns state + lifecycle hooks
│
▼
[Template Function Produces HTML]
• Template literals ${} evaluated
• Returns HTML string
│
▼
─ onBeforeMount ─
│
▼
[Renderer: Diff → Patch]
• Two-pointer diffing algorithm
• Key-based reconciliation
• Minimal DOM mutations
│
▼
[TemplateEngine Processes]
• Evaluates @event expressions
• Binds event listeners to DOM
• Evaluates :prop expressions
│
▼
[Inject Styles]
│
▼
[Mount Child Components]
│
▼
─ onMount ─
│
▼
┌────────────────────────────────────────────────────┐
│ ↺ REACTIVE CYCLE │
├────────────────────────────────────────────────────┤
│ │
│ [Idle: Waiting for Signal Change] ◄──────┐ │
│ │ │ │
│ ┌───────────────────┼───────────────────┐ │ │
│ ▼ ▼ ▼ │ │
│ [User Event] [Signal.value = x] [emitter] │ │
│ │ │ │ │ │
│ └───────────────────┼───────────────────┘ │ │
│ ▼ │ │
│ [queueMicrotask Batching] │ │
│ • Multiple changes collapsed │ │
│ • Single render scheduled │ │
│ │ │ │
│ ▼ │ │
│ [Template Re-evaluation] │ │
│ │ │ │
│ ▼ │ │
│ ─ onBeforeUpdate ─ │ │
│ │ │ │
│ ▼ │ │
│ [Renderer: Diff → Patch] │ │
│ │ │ │
│ ▼ │ │
│ [TemplateEngine Processes] │ │
│ • Re-binds @events │ │
│ • Re-evaluates :props │ │
│ │ │ │
│ ▼ │ │
│ ─ onUpdate ──────────────────┘ │
│ │
└────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ ELEVA DATA FLOW │
├─────────────────────────────────────────────────────────────┤
│ │
│ [Component Registration] │
│ │ │
│ ▼ │
│ [Mounting & Context Creation] │
│ │ │
│ ▼ │
│ [setup() Execution] ──► Returns { state, hooks } │
│ │ │
│ ▼ │
│ [template() Produces HTML] │
│ │ │
│ ▼ │
│ [onBeforeMount] │
│ │ │
│ ▼ │
│ [Renderer.patchDOM()] ──► Diff & patch changes │
│ │ │
│ ▼ │
│ [TemplateEngine] ──► Bind @events, eval :props │
│ │ │
│ ▼ │
│ [onMount] │
│ │ │
│ ▼ │
│ ┌─────────────────── ↺ REACTIVE CYCLE ───────────────────┐ │
│ │ │ │
│ │ [Idle: Waiting] ◄─────────────────────────────────┐ │ │
│ │ │ │ │ │
│ │ ▼ │ │ │
│ │ [User Interaction] ──► Event Handler │ │ │
│ │ │ │ │ │
│ │ ▼ │ │ │
│ │ [signal.value = newValue] │ │ │
│ │ │ │ │ │
│ │ ▼ │ │ │
│ │ [queueMicrotask batching] │ │ │
│ │ │ │ │ │
│ │ ▼ │ │ │
│ │ [template() Re-evaluation] │ │ │
│ │ │ │ │ │
│ │ ▼ │ │ │
│ │ [onBeforeUpdate] │ │ │
│ │ │ │ │ │
│ │ ▼ │ │ │
│ │ [Renderer.patchDOM()] │ │ │
│ │ │ │ │ │
│ │ ▼ │ │ │
│ │ [TemplateEngine] ──► Process @events (new nodes) │ │ │
│ │ │ │ │ │
│ │ ▼ │ │ │
│ │ [onUpdate] ───────────────────────────────────────┘ │ │
│ │ │ │
│ └────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
| Benefit | Description |
|---|---|
| Modularity | Each component encapsulates its own logic and state |
| Efficiency | Only changed DOM parts are updated |
| Predictability | One-way data flow (state → template → DOM) |
| Extensibility | Clear separation of concerns enables plugins |
┌─────────────────────────────────────────────────────────────┐
│ Eleva (Core) │
│ │
│ ┌─────────┐ ┌────────────────┐ ┌──────────────────┐ │
│ │ Signal │◄──►│ TemplateEngine │◄──►│ Renderer │ │
│ └─────────┘ └────────────────┘ └──────────────────┘ │
│ │ │ │ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ Component │ │
│ │ • setup() creates signals │ │
│ │ • template() uses TemplateEngine for @events/:props │ │
│ │ • Renderer patches DOM on signal changes │ │
│ └───────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────┐ │
│ │ Emitter │ ◄── Inter-component communication │
│ └─────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
Eleva’s TemplateEngine evaluates expressions in @events and :props attributes using JavaScript’s Function constructor with with statement:
// Internal implementation (simplified)
new Function("data", `with(data) { return ${expression}; }`);
This is a standard pattern used by major frameworks including Vue, Angular, and Svelte for template expressions. It enables powerful, flexible templates while maintaining a clear security boundary.
Eleva’s security model assumes templates are developer-authored code, not user-generated content.
| Template Source | Trusted | Security Status |
|---|---|---|
| Developer-written components | Yes | Safe |
| Build-time compiled templates | Yes | Safe |
| User-supplied strings | No | Do not use |
| Database-stored user content | No | Escape before display |
// SAFE: Developer-authored template with dynamic data
app.component("UserGreeting", {
setup: ({ signal }) => {
const userName = signal("Alice");
return { userName };
},
template: (ctx) => `
<h1>Hello, ${ctx.userName.value}</h1>
`
});
// SAFE: Displaying user content (data, not template)
app.component("Comment", {
setup: ({ props }) => ({
// User content is DATA, safely interpolated as text
content: props.content
}),
template: (ctx) => `
<div class="comment">${ctx.content}</div>
`
});
// SAFE: Event handlers defined by developer
app.component("Button", {
setup: ({ signal }) => {
const handleClick = () => console.log("Clicked");
return { handleClick };
},
template: (ctx) => `
<button @click="handleClick">Click me</button>
`
});
// UNSAFE: Never construct templates from user input
const userTemplate = getUserInput(); // From form, URL, etc.
app.component("Dangerous", {
template: () => userTemplate // XSS vulnerability!
});
// UNSAFE: Never interpolate user strings into event handlers
const userHandler = getUserInput();
template: () => `<button @click="${userHandler}">Click</button>` // Code injection!
// UNSAFE: Never use user input in :props expressions
const userExpression = getUserInput();
template: () => `<child-comp :data="${userExpression}"></child-comp>` // Code injection!
Note: This security model is identical to Vue’s template expressions, Angular’s property binding, and React’s JSX. The pattern is safe when templates are part of your application’s source code, which is the standard and intended use case.
| ← Components | Back to Main Docs | Plugin System → |