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.

Tokens
28.4K
Snippets
158
Records
200
Agent score
64%

What's inside OpenComponents

  1. Overview of OpenComponents Micro Frontend Architecture

    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.
  2. 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.
  3. 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.json and components-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.json files are still fetched from storage via getComponentInfo.
    • Component reads are served from an in-memory cache and do not hit the database on the hot path.
  4. 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.
  5. 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.
  6. 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.
  7. OpenComponents rendering lifecycle flow

    The OC client follows this sequence to render components:

    1. Initialization: Client loads and fires oc:ready.
    2. Discovery: Scans DOM for <oc-component> tags.
    3. Fetching: Sets data-rendering=true, shows loading message, and fetches the component from the registry (with retry logic).
    4. Processing: Loads template externals and renders the HTML.
    5. Injection: Injects HTML into the DOM, sets data-rendered=true, and fires oc:rendered.
    6. Activation: If it is an ESM component, the mount function is called; otherwise, scripts are reactivated.
    7. Loop: Returns to discovery to find any remaining or nested components.
  8. Implement context-aware plugins for components

    Setting context: true during 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: true is enabled, the plugin's execute function receives a context object containing name (the component name) and version (the component version). The execute function must return the actual function that will be exposed to the component via context.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"),
    });
  9. 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.json every 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 fallbackRegistryUrl to allow a secondary registry to serve a component if it is missing locally.
  10. Implement server-side logic using the Server API

    Modern OpenComponents use the Server API from oc-server within src/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",
        };
      });
  11. Install the OC Client script

    The oc-client is 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 call oc.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>
  12. 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 an href pointing to the component version and including the oc-client JavaScript library. It is recommended to use protocol-less URLs to ensure HTTPS is used where possible. The /oc-client/client.js path 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>