Version: 1.0.0 This guide covers creating, installing, and using plugins to extend Eleva’s functionality.
The Plugin System provides a powerful way to extend the framework’s functionality. Plugins can add new features, modify existing behavior, or integrate with external libraries.
A plugin in Eleva is an object with three required properties:
const MyPlugin = {
name: "myPlugin", // Unique identifier for the plugin
version: "1.0.0", // Semantic version string
install(eleva, options) {
// Plugin installation logic
},
};
| Property | Type | Description |
|---|---|---|
name |
string | Unique identifier for the plugin |
version |
string | Semantic version (e.g., “1.0.0”) |
install |
function | Receives Eleva instance and options |
Plugins are installed using the use method:
const app = new Eleva("myApp");
app.use(MyPlugin, { /* optional configuration */ });
The use method:
install function with the Eleva instance and optionsinstall(eleva) {
eleva.newMethod = () => { /* ... */ };
}
install(eleva) {
eleva.component("enhanced-component", {
template: (ctx) => `...`,
setup: (ctx) => ({ /* ... */ })
});
}
install(eleva) {
const originalMount = eleva.mount;
eleva.mount = function(container, compName, props) {
// Add pre-mount logic
const result = originalMount.call(this, container, compName, props);
// Add post-mount logic
return result;
};
}
install(eleva) {
eleva.services = {
api: new ApiService(),
storage: new StorageService()
};
}
eleva-{plugin-name} for published pluginsHere’s a complete example of a custom plugin:
const Logger = {
name: "logger",
version: "1.0.0",
install(eleva, options = {}) {
const { level = "info" } = options;
// Add logging methods to Eleva instance
eleva.log = {
info: (msg) => console.log(`[INFO] ${msg}`),
warn: (msg) => console.warn(`[WARN] ${msg}`),
error: (msg) => console.error(`[ERROR] ${msg}`),
};
// Enhance component mounting with logging
const originalMount = eleva.mount;
eleva.mount = async function(container, compName, props) {
eleva.log.info(`Mounting component: ${compName}`);
const result = await originalMount.call(this, container, compName, props);
eleva.log.info(`Component mounted: ${compName}`);
return result;
};
},
};
// Usage
const app = new Eleva("myApp");
app.use(Logger, { level: "debug" });
install function is called with the instance and optionsEleva provides TypeScript declarations for plugin development:
interface ElevaPlugin {
name: string;
version: string;
install(eleva: Eleva, options?: Record<string, any>): void;
}
This ensures type safety when developing plugins in TypeScript.
Eleva comes with three powerful built-in plugins:
| Plugin | Purpose | Size | Docs |
|---|---|---|---|
| Attr | ARIA, data-*, boolean attributes | ~2.4KB | View → |
| Router | Client-side routing & guards | ~15KB | View → |
| Store | Global state management | ~6KB | View → |
Advanced attribute handling with ARIA support:
import { Attr } from 'eleva/plugins';
app.use(Attr, {
enableAria: true,
enableData: true,
enableBoolean: true,
enableDynamic: true
});
Features:
Client-side routing with reactive state:
import { Router } from 'eleva/plugins';
const router = app.use(Router, {
mount: '#app',
mode: 'hash',
routes: [
{ path: '/', component: HomePage },
{ path: '/about', component: AboutPage },
{ path: '/users/:id', component: UserPage }
]
});
await router.start();
Features:
Centralized state management:
import { Store } from 'eleva/plugins';
app.use(Store, {
state: { count: 0, user: null },
actions: {
increment: (state) => state.count.value++,
setUser: (state, user) => state.user.value = user
},
persist: { key: "app-state", storage: "localStorage" }
});
Features:
import Eleva from 'eleva';
import { Attr, Router, Store } from 'eleva/plugins';
const app = new Eleva("MyApp");
// Install plugins
app.use(Attr);
app.use(Store, { state: {} });
app.use(Router, { routes: [] });
| Plugin | Minified | Gzipped |
|---|---|---|
| Core | ~6KB | ~2.3KB |
| Attr | ~2.4KB | ~1KB |
| Router | ~15KB | ~5KB |
| Store | ~6KB | ~2KB |
// my-analytics-plugin.js
export const Analytics = {
name: "analytics",
version: "1.0.0",
install(eleva, options = {}) {
const { trackingId, debug = false } = options;
// Initialize analytics
if (debug) {
console.log(`Analytics initialized with ID: ${trackingId}`);
}
// Add tracking methods
eleva.analytics = {
track(event, data) {
if (debug) {
console.log(`[Analytics] ${event}:`, data);
}
// Send to analytics service
},
page(path) {
this.track('pageview', { path });
}
};
// Auto-track component mounts
const originalMount = eleva.mount;
eleva.mount = async function(container, compName, props) {
const result = await originalMount.call(this, container, compName, props);
eleva.analytics.track('component_mount', { component: compName });
return result;
};
}
};
import Eleva from 'eleva';
import { Analytics } from './my-analytics-plugin.js';
const app = new Eleva("MyApp");
app.use(Analytics, {
trackingId: 'UA-XXXXX-Y',
debug: true
});
// Now available throughout your app
app.analytics.track('button_click', { button: 'signup' });
// package.json
{
"name": "eleva-plugin-analytics",
"version": "1.0.0",
"main": "dist/index.js",
"peerDependencies": {
"eleva": "^1.0.0"
}
}
install(eleva) {
const originalMount = eleva.mount.bind(eleva);
eleva.mount = async (container, compName, props) => {
// Inject custom utilities into setup context
const enhancedProps = {
...props,
myUtility: () => { /* ... */ }
};
return originalMount(container, compName, enhancedProps);
};
}
install(eleva) {
eleva.onComponentMount = (callback) => {
const originalMount = eleva.mount.bind(eleva);
eleva.mount = async (...args) => {
const result = await originalMount(...args);
callback(result);
return result;
};
};
}
install(eleva) {
const events = new Map();
eleva.bus = {
on(event, handler) {
if (!events.has(event)) events.set(event, []);
events.get(event).push(handler);
return () => this.off(event, handler);
},
off(event, handler) {
const handlers = events.get(event);
if (handlers) {
const index = handlers.indexOf(handler);
if (index > -1) handlers.splice(index, 1);
}
},
emit(event, data) {
const handlers = events.get(event);
if (handlers) handlers.forEach(h => h(data));
}
};
}
| ← Architecture | Back to Main Docs | Best Practices → |