OpenComponents Documentation
website·Indexed 29 days ago
https://opencomponents.github.io/A language-agnostic micro frontend framework that enables independent teams to build, publish, and version UI components. The documentation covers the component lifecycle, CLI usage, registry configuration, and both client-side and server-side rendering strategies.
What's inside OpenComponents
- OpenComponents is a pragmatic, language-agnostic approach to micro frontends that allows multiple autonomous teams to own different parts of a UI. It solves common monolith problems such as coordination overhead, technology lock-in, and deployment bottlenecks by allowing teams to work independently with their preferred tools and release components on their own schedules.
Overview of OpenComponents Micro Frontend Framework
OpenComponents is a language-agnostic micro frontend framework. It enables independent teams to build, publish, and version UI components as isomorphic HTML/CSS/JS bundles. These components can be rendered and consumed by any backend (such as Node.js, .NET, PHP, Java, or Go) via a simple HTTP + HTML contract.Overview of OpenComponents Registry Metadata Stores
Registry metadata stores (available since v0.50.56) move the registry's metadata index—the list of existing components and versions—from derived static files (
components.jsonandcomponents-details.json) into a pluggable database.Key benefits include:
- Publish Performance: Changes publish operations from an O(registry size) scan and rewrite to an O(1) atomic row append.
- Startup Speed: Replaces directory walking with a single database query.
- Consistency: Uses database PRIMARY KEY constraints (
component_name,version) to prevent race conditions during concurrent publishes across multiple nodes.
What remains unchanged:
- Component bundles (static files) still reside in the configured storage adapter (e.g., S3, Azure Blob).
package.jsonfiles are still fetched from storage viagetComponentInfo.- Component reads are served from an in-memory cache and do not hit the database on the hot path.
Understand OpenComponents micro frontend framework
OpenComponents is a framework for building micro frontends—small, independent UI components that can be developed by different teams and composed into larger applications. Unlike framework-specific components, OpenComponents are framework-agnostic (working across React, Vue, Angular, etc.), can be deployed and updated independently, and possess their own server-side logic and data fetching.Understand OpenComponents core architecture pieces
OpenComponents consists of four primary architectural elements:
- Component: A small, versioned bundle containing the view and optional server-side logic.
- Registry: A REST API responsible for storing, versioning, and serving components.
- Library: The storage backend (e.g., S3, Google Cloud Storage, Azure) used by the registry to persist published components.
- Client: The runtime (Browser, Node.js, PHP, Ruby) that discovers and renders the components.
OpenComponents System Architecture Overview
OpenComponents decomposes monolithic frontends into independently deployable, reusable components. The architecture consists of four core pillars:
- CLI & Development Tools: Handles component scaffolding, local development with hot reload, publishing, and debugging.
- Registry (REST API): Manages the component catalog, metadata, version resolution, authentication, and rendering.
- Component Library: Provides immutable storage for published component versions and artifacts.
- CDN & Asset Distribution: Serves static assets (JS, CSS, images) with edge caching.
OpenComponents rendering lifecycle flow
The OC client follows this sequence to render components:
- Initialization: Client loads and fires
oc:ready. - Discovery: Scans DOM for
<oc-component>tags. - Fetching: Sets
data-rendering=true, shows loading message, and fetches the component from the registry (with retry logic). - Processing: Loads template externals and renders the HTML.
- Injection: Injects HTML into the DOM, sets
data-rendered=true, and firesoc:rendered. - Activation: If it is an ESM component, the
mountfunction is called; otherwise, scripts are reactivated. - Loop: Returns to discovery to find any remaining or nested components.
- Initialization: Client loads and fires
Implement context-aware plugins for components
Setting
context: trueduring registration allows a plugin to receive information about the specific component calling it. This is useful for security validation, audit logging, rate limiting, and version-specific logic.When
context: trueis enabled, the plugin'sexecutefunction receives a context object containingname(the component name) andversion(the component version). Theexecutefunction must return the actual function that will be exposed to the component viacontext.plugins.// ./registry/oc-plugins/feature-manager.js module.exports.register = function (options, dependencies, next) { // Initialization logic next(); }; module.exports.execute = function (context) { // context contains { name, version } return function (featureName) { if (context.version.startsWith("2.")) { return "New API"; } return "Legacy API"; }; }; // Registration registry.register({ name: "featureManager", context: true, register: require("./oc-plugins/feature-manager"), });Manage component distribution and registry synchronization
OpenComponents supports a multi-registry architecture where multiple registry instances (e.g., US-East, EU-West) share a common CDN.
Synchronization Mechanism:
- Registries poll
components.jsonevery 5 seconds. - They detect changes via file hash comparisons.
- New/updated metadata is downloaded and compiled templates/server logic are stored in memory.
- If a network partition occurs, registries may serve stale but functional versions of components.
Mitigation Strategies:
- Semantic Versioning: Use ranges (e.g.,
~1.2.0) instead of pinning exact versions (e.g.,1.2.4) to tolerate slight sync delays. - Fallback Registries: Configure
fallbackRegistryUrlto allow a secondary registry to serve a component if it is missing locally.
- Registries poll
Implement server-side logic using the Server API
Modern OpenComponents use theServerAPI fromoc-serverwithinsrc/entry.server.ts. This API allows you to define expected parameters, a main request handler, and optional actions. The handler returns a JSON object that is passed as props to the client-side component.import { Server } from "oc-server"; export const server = new Server() .withParameters({ name: { type: "string", default: "Guest" }, theme: { type: "string", default: "light" }, }) .handler(async (params) => { const now = new Date(); return { name: params.name ?? "Guest", theme: params.theme ?? "light", currentTime: now.toLocaleTimeString(), cssClass: params.theme === "dark" ? "dark-theme" : "light-theme", }; });Install the OC Client script
Theoc-clientis served by every registry. Load it using a protocol-relative URL to support both HTTP and HTTPS. For optimal performance, place the script tag just before the closing</body>tag. If the script is injected before the components, you must manually calloc.renderUnloadedComponents()once the client is ready.<!-- Always served at the same version as your registry --> <script src="//your-registry.company.com/oc-client/client.js"></script>Integrate OpenComponents for client-side rendering
To enable client-side rendering, you must have a publicly available components registry. You integrate components by using the<oc-component>tag with anhrefpointing to the component version and including theoc-clientJavaScript library. It is recommended to use protocol-less URLs to ensure HTTPS is used where possible. The/oc-client/client.jspath is a shortcut to serve the client version that matches the registry version.<html> <head></head> <body> <oc-component href="//my-components-registry.mydomain.com/hello-world/1.X.X" ></oc-component> <script src="//my-components-registry.mydomain.com/oc-client/client.js"></script> </body> </html>