Symbiote.js is a lightweight, standards-first JavaScript library for creating Web Components with reactive state and built-in data flow management, running directly in the browser without a build step.
What is Symbiote.js?
Symbiote.js is a UI library that lets developers build reusable custom elements using plain JavaScript, HTML templates, and standard Web Components APIs. It accepts component definitions (classes with state, template strings, and CSS) and outputs real custom elements that work in any HTML page or framework. The library is maintained by rnd-pro.com, released under the MIT license, and distributed on npm as @symbiotejs/symbiote. It is designed to extend platform APIs rather than replace them, avoiding virtual DOM and compilers entirely.
Key Features
- Natural DOM Extension — Components are standard custom elements, so state can be read and written from outside using the
$property, e.g.,document.querySelector('my-counter').$.count = 42, with no framework adapters. - Runtime-Agnostic Templates — Templates are plain HTML strings using the
htmltagged template function, which supports two interpolation modes: object bindings for reactive handlers and string concatenation for values. - App-wide State Management — Built-in
PubSuballows named data contexts likeAPP/userto be shared across components, and thectxattribute groups components into a shared context using*-prefixed properties, eliminating prop drilling. - Server-Side Rendering — v3.x includes
SSR.processHtml()andSSR.renderToStream()for rendering components to HTML, plus client-side hydration viassrMode;isoModemakes a single component work for both SSR and client-only scenarios. - Itemize for Dynamic Lists — The
itemizeattribute renders arrays or objects into reactive lists with efficient updates, and can be combined with alazyattribute to defer rendering of large data sets based on viewport visibility. - Optional Shadow DOM — Components can use light DOM for styling with regular CSS or opt into Shadow DOM via
shadowStyles; CSS variables,::part(), nesting, and container queries all work natively. - Application Router — An optional
AppRoutermodule supports path patterns with:paramextraction, route guards, and lazy loading of components. - WebMCP Support — v3.x can expose live component actions as browser-native tools for AI agents through the WebMCP protocol.
Who is Symbiote.js for?
- Front-end developers building widgets — Embed complex interactive components into any existing web page without worrying about conflicts with the host framework.
- Micro-frontend architects — Ship standard custom elements that can be consumed by React, Vue, Angular, or plain HTML applications with no adapter layer.
- Component library maintainers — Author a single reusable component set that works across frameworks and can take advantage of optional SSR for SEO-friendly rendering.
- Low-code and AI-first developers — Take advantage of declarative templates and the automatic WebMCP tool exposure to make app state accessible to AI agents.
What can you do with Symbiote.js?
- Build reactive counters and forms — Define a class extending
Symbiote, set a template withhtml, and register the element withMyCounter.reg('my-counter'); state changes update the DOM synchronously. - Share state between unrelated components — Use
ctx="gallery"on several components so they all read and write the same*filesarray without a parent component or global store. - Render lists efficiently — Use
itemizewith atemplateelement to output lists that update when the underlying data array changes. - Create SSR-powered applications — Pre-render components on the server and hydrate them on the client using
ssrModeorisoMode, with support for Declarative Shadow DOM.
How does Symbiote.js work?
The quick start shows a component defined in a module script: import the library from the CDN (https://esm.run/@symbiotejs/symbiote), extend the Symbiote base class, declare state as class fields, write a template with the html function, and call reg() to define the custom element. The library then observes property changes and updates bindings directly in the DOM. For npm users, the package can be installed with npm i @symbiotejs/symbiote.
Alternatives
- Lit — Another widely used Web Components library. Symbiote.js positions itself as extending platform APIs rather than replacing them and offers built-in state management and SSR features.
FAQ
Does Symbiote.js require a build step?
No. Symbiote.js works directly in the browser via esm.run CDN import for development. A bundler is recommended for production performance but is entirely optional.
Is Symbiote.js free?
Yes. Symbiote.js is open source under the MIT license and available on npm as @symbiotejs/symbiote.
What is the difference between Symbiote.js and Lit?
Symbiote.js is designed to extend standard platform APIs, while Lit provides a reactive template system on top of Web Components. Symbiote.js also includes app-wide state management and optional SSR that can hybridize with client rendering out of the box.
Does Symbiote.js support server-side rendering?
Yes. Version 3.x includes SSR.processHtml() and SSR.renderToStream(), and an isoMode flag lets a single component automatically hydrate existing server-rendered markup or fall back to client-side rendering.





