Version: 1.0.0 Answers to common questions, testing guide, and troubleshooting tips.
Q: What is Eleva?
Eleva is a minimalist, lightweight (6KB) pure vanilla JavaScript frontend framework. It provides React-like component-based architecture with signal-based reactivity, but without the complexity, dependencies, or mandatory build tools of larger frameworks.
Q: Is Eleva production-ready?
Yes! Eleva v1.0.0 is the first official stable release. The framework is production-ready with a stable API and comprehensive test coverage. We continue to welcome feedback and contributions.
Q: How do I report issues or request features?
Please use the GitHub Issues page.
Q: What is the difference between Eleva and React?
Eleva differs from React in several key ways:
Choose Eleva when bundle size and performance matter without build complexity; choose React when you need its extensive ecosystem and tooling.
Q: What is the difference between Eleva and Vue?
Both Eleva and Vue are progressive frameworks, but Eleva is smaller (6KB vs 34KB), has zero dependencies, and requires no build tools. Vue offers a more comprehensive ecosystem with Vue Router, Vuex/Pinia, and extensive tooling. Eleva’s plugins (Router, Store) provide similar functionality in a lighter package.
Q: What is the difference between Eleva and Svelte?
Svelte compiles components at build time, resulting in very small runtime code (~2KB), but requires a build step. Eleva (6KB) works without any build tools via CDN. Both avoid virtual DOM. Choose Eleva when avoiding build complexity; choose Svelte when you’re already using a bundler.
Q: Is Eleva a React alternative?
Yes, Eleva can serve as a lightweight React alternative for projects that don’t need React’s full ecosystem. Eleva offers similar component-based architecture and reactivity patterns but with a much smaller footprint.
Q: How does Eleva’s reactivity work?
Eleva uses a signal-based reactivity system similar to Solid.js. Signals are reactive containers that hold values. When a signal’s value changes, any component or watcher subscribed to that signal automatically updates.
Q: Does Eleva use Virtual DOM?
No. Eleva uses real DOM manipulation with an efficient diffing algorithm. Instead of maintaining a virtual DOM tree in memory, Eleva directly patches the real DOM. This reduces memory overhead and delivers 240fps-capable performance.
Q: Can I use Eleva with TypeScript?
Absolutely! Eleva includes built-in TypeScript declarations (.d.ts files). No additional @types packages are needed.
Q: Does Eleva require a build step?
No. Eleva can be used directly via CDN without any build tools, bundlers, or transpilers. However, you can also use Eleva with bundlers like Vite, Webpack, or Rollup if you prefer.
Q: Is Eleva suitable for large applications?
Eleva’s performance scales well—it handles 10K+ rows efficiently (via virtual scrolling), achieves 240fps rendering, and its Router/Store plugins support complex SPAs. The main consideration for large applications is ecosystem maturity: React, Vue, and Angular offer more extensive tooling, testing libraries, and community resources.
Q: Does Eleva include routing capabilities?
Yes! Eleva includes a powerful Router plugin that provides client-side routing with navigation guards, reactive state, and component resolution. Import it from eleva/plugins.
Q: What plugins are available with Eleva?
Eleva comes with three built-in plugins:
Q: Can I create custom plugins for Eleva?
Yes! Eleva has a simple plugin API. Plugins are objects with an install(eleva, options) method. See the Plugin System guide for details.
Q: How do I migrate from React to Eleva?
Migration involves:
useState with Eleva’s signal()useEffect with signal watchers or lifecycle hooksSee the React Migration Guide for detailed examples.
Q: How do I migrate from Vue to Eleva?
Migration involves:
See the Vue Migration Guide for detailed examples.
Q: How do I migrate from Alpine.js to Eleva?
Both share a similar philosophy—lightweight, no build step. Migration involves:
x-data with setup() + signal()x-show/x-if to ternary expressionsx-for with .map().join('')x-model to value + @input patternSee the Alpine.js Migration Guide for detailed examples.
Eleva has a comprehensive test suite ensuring reliability and stability.
| Metric | Value |
|---|---|
| Total Tests | 273 |
| Line Coverage | 100% |
| Function Coverage | 100% (core) |
| Test Runner | Bun |
# Run all tests
bun test
# Run with coverage report
bun test:coverage
# Run unit tests only
bun test test/unit
# Run performance benchmarks
bun test:benchmark
# Run prepublish checks (lint + test + build)
bun run prepublishOnly
test/
├── unit/ # Unit tests
│ ├── core/ # Core Eleva tests
│ │ └── Eleva.test.ts
│ ├── modules/ # Module tests
│ │ ├── Emitter.test.ts
│ │ ├── Renderer.test.ts
│ │ ├── Signal.test.ts
│ │ └── TemplateEngine.test.ts
│ └── plugins/ # Plugin tests
│ ├── Attr.test.ts
│ ├── Router.test.ts
│ └── Store.test.ts
└── performance/ # Performance benchmarks
├── fps-benchmark.test.ts
└── js-framework-benchmark.test.ts
Eleva uses Bun’s built-in test runner with a Jest-compatible API:
import { describe, test, expect, beforeEach } from "bun:test";
import Eleva from "../../src/index.js";
describe("MyComponent", () => {
let app: Eleva;
beforeEach(() => {
document.body.innerHTML = `<div id="app"></div>`;
app = new Eleva("TestApp");
});
test("should mount correctly", async () => {
const component = {
setup: ({ signal }) => ({ count: signal(0) }),
template: (ctx) => `<div>${ctx.count.value}</div>`
};
const instance = await app.mount(
document.getElementById("app")!,
component
);
expect(instance).toBeTruthy();
expect(document.body.innerHTML).toContain("0");
});
});
Problem: Component doesn’t appear in the DOM.
Solutions:
const container = document.getElementById("app");
if (!container) {
console.error("Container not found!");
}
app.mount(container, "MyComponent");
Problem: Signal value changes but UI doesn’t update.
Solutions:
.value to read signals in templates:
// Wrong
template: (ctx) => `<p>${ctx.count}</p>`
// Correct
template: (ctx) => `<p>${ctx.count.value}</p>`
.value, not the signal itself:
// Wrong
count = 5;
// Correct
count.value = 5;
Problem: @click or other event handlers don’t fire.
Solutions:
ctx. in event handlers:
// Wrong
@click="ctx.handleClick"
// Correct
@click="handleClick"
@click="() => count.value++"
Problem: Child component doesn’t receive props.
Solutions:
ctx. in :prop attributes:
// Wrong
:user="ctx.userData.value"
// Correct
:user="userData.value"
children:
children: {
".child-selector": "ChildComponent"
}
Problem: Application becomes slow over time.
Solutions:
onUnmount:
setup: ({ signal }) => {
let interval = null;
return {
onMount: () => {
interval = setInterval(() => {}, 1000);
},
onUnmount: () => {
clearInterval(interval);
}
};
}
// Log signal changes
const count = signal(0);
count.watch((newVal, oldVal) => {
console.log(`Count changed: ${oldVal} → ${newVal}`);
});
// Debug template rendering
template: (ctx) => {
console.log("Rendering with context:", ctx);
return `<div>${ctx.count.value}</div>`;
}
// Check mounted instance
const instance = await app.mount(container, "MyComponent");
console.log("Mounted instance:", instance);
| Method | Description | Returns |
|---|---|---|
new Eleva(name) |
Create app instance | Eleva |
app.component(name, def) |
Register component | Eleva |
app.mount(el, name, props?) |
Mount to DOM | Promise<MountResult> |
app.use(plugin, options?) |
Install plugin | Eleva or plugin result |
| Method | Description |
|---|---|
signal(value) |
Create reactive state |
signal.value |
Read/write current value |
signal.watch(fn) |
Subscribe to changes |
| Method | Description |
|---|---|
emitter.on(event, fn) |
Subscribe to event |
emitter.off(event, fn) |
Unsubscribe from event |
emitter.emit(event, data) |
Emit event |
For detailed API documentation, see the individual module guides:
Join our community for support, discussions, and collaboration:
| Channel | Purpose | Link |
|---|---|---|
| GitHub Discussions | General questions, ideas | Discussions |
| GitHub Issues | Bug reports, feature requests | Issues |
| Stack Overflow | Technical questions | eleva, eleva.js |
| Community projects | r/elevajs | |
| Discord | Real-time chat | Join |
| Telegram | Support, feedback | Join |
Contributions are welcome! Whether you’re fixing bugs, adding features, or improving documentation, your input is invaluable.
See the CONTRIBUTING file for guidelines.
For a detailed log of all changes and updates, please refer to the Changelog.
Eleva is open-source and available under the MIT License.
| ← Best Practices | Back to Main Docs | Examples → |