Symbiote.js isn't just another frontend library - it's a groundbreaking approach to web development that harnesses the full power of native web technologies.
Here's what sets it apart:
Unlike frameworks that create opaque abstractions and complex runtime environments, Symbiote.js extends the native DOM API directly. This means:
Symbiote.js takes a refreshingly straightforward approach to templating:
// Define templates anywhere
const myTemplate = html`
<div class="my-component">
<h1>{{title}}</h1>
<div>{{content}}</div>
</div>
`;
// Use with any server-side technology
const serverTemplate = /*html*/ `
<div class="server-rendered">
<h1 bind="textContent: title">SSR Title</h1>
<div bind="textContent: content">SSR Content</div>
</div>
`;
Symbiote.js introduces an innovative approach to component communication and state management:
// Inherited context (^)
html`<button ${{onclick: '^onButtonClicked'}}>Click me!</button>`;
// Shared context (*)
html`<div>{{*sharedProperty}}</div>`;
// Named context (/)
html`<div>{{APP/someProperty}}</div>`;
<script type="importmap">
{
"imports": {
"@symbiotejs/symbiote": "https://esm.run/@symbiotejs/symbiote"
}
}
</script>
<script type="module">
import Symbiote, { html, css } from '@symbiotejs/symbiote';
export class MyComponent extends Symbiote {
// Initialize state:
init$ = {
count: 0,
increment: () => {
this.$.count++;
},
}
}
// Define template:
MyComponent.template = html`
<h2>{{count}}</h2>
<button ${{onclick: 'increment'}}>Click me!</button>
`;
// Add styles:
MyComponent.rootStyles = css`
my-component {
color: #f00;
}
`;
// Register the custom element:
MyComponent.reg('my-component');
</script>
<my-component></my-component>
This complete HTML example shows everything you need to run a Symbiote.js application. While this demonstrates core concepts, real-world projects can leverage any development toolchain including TypeScript, bundlers, linters and other modern tooling.