npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@ly-sys/layout-protocol

v1.0.3

Published

Specification, data models, and service interfaces for the layout candidate communication protocol.

Readme

@ly-sys/layout-protocol

Specification, data models, and service interfaces for the layout candidate communication protocol.

npm version package manager

The @ly-sys/layout-protocol package defines the formal specifications, types, and services utilized by the layout system to orchestrate dynamic style injection. It is engineered specifically for decoupled architectures, such as * Micro-Frontends (MFE)* and Server-Side Rendering (SSR).


Key Features

  • Decoupled Architecture: Remotes register style "candidates" they need at runtime without bundling static CSS sheets.
  • Prefix Decoupling: Candidates are collected prefix-free (e.g. "gap-4"). Hosts prepend their configured prefix at runtime, enabling MFEs to run on hosts with different prefixes without rebuilds.
  • Constant Memory Footprint: Collector deduplicates candidates on-the-fly, keeping memory overhead $O(1)$.
  • Module Federation Service: Features LayoutService for DI (Dependency Injection) containers, coordinating critical and deferred style injection between remotes and hosts.

Architecture

The protocol is designed around a state collector that intercepts layout components during render cycles and flushes them as a structured batch payload.

SSR / Rendering Collection Flow

sequenceDiagram
    participant MFE as Micro-Frontend (Remote)
    participant Provider as LayoutProvider (Decorator)
    participant Engine as LayoutEngine Core
    participant Collector as CandidateCollector

    Note over MFE,Collector: 1. Instantiation per Request
    MFE->>Collector: createCandidateCollector()
    MFE->>Provider: <LayoutProvider engine={engine} collector={collector}>
    
    Note over Provider,Engine: 2. Transparent Engine Decoration
    Provider->>Engine: Intercepts parseResponsive()

    Note over MFE,Provider: 3. Render and Registration
    MFE->>Provider: <Flex gap={{ base: 2, md: 4 }}>
    Provider->>Engine: engine.parseResponsive()
    Engine-->>Provider: Returns "ly-gap-2 md:ly-gap-4"
    Provider->>Collector: collector.add("gap-2", undefined)
    Provider->>Collector: collector.add("gap-4", "md")
    
    Note over MFE,Collector: 4. Extraction (Flush)
    MFE->>Collector: collector.flush()
    Collector-->>MFE: Returns CandidateBatch and resets internal state

Installation

pnpm add @ly-sys/layout-protocol
# or
npm install @ly-sys/layout-protocol
# or
yarn add @ly-sys/layout-protocol

Usage Guide & API Reference

1. Candidate Collector API

Use createCandidateCollector to track style classes and raw styles:

import {createCandidateCollector} from "@ly-sys/layout-protocol";

// 1. Create a collector
const collector = createCandidateCollector();

// 2. Add candidates (utilities must be prefix-free)
collector.add("flex-row");
collector.add("gap-4", "md");

// 3. Add custom raw inline CSS (e.g. from minChildWidth grid rules)
collector.addRawCSS({
    critical: ".custom-grid { display: grid; }",
    deferable: ".custom-grid:hover { opacity: 0.9; }"
});

// 4. Flush the batch (returns the batch data and resets the collector state)
const batch = collector.flush();
console.log(batch);
/*
Output:
{
  candidates: [
    { utility: "flex-row", breakpoint: undefined },
    { utility: "gap-4", breakpoint: "md" }
  ],
  rawCSS: {
    critical: ".custom-grid { display: grid; }",
    deferable: ".custom-grid:hover { opacity: 0.9; }"
  }
}
*/

2. LayoutService (Module Federation & MFE Orchestration)

In distributed frontends, remotes shouldn't duplicate style compilation. Instead, they share a singleton LayoutService registered in a DI (Dependency Injection) container.

Host Configuration (DI container initialization)

import {createLayoutService} from "@ly-sys/layout-protocol";
import {createLayoutEngine} from "@ly-sys/layout-engine";

const hostEngine = createLayoutEngine({libPrefix: "ly"});

// Bind to DI container as a singleton
const layoutService = createLayoutService({
    engine: hostEngine,
    // Custom critical style injector (defaults to DOM insertion)
    criticalInjector: (css, remoteName) => {
        console.log(`Injecting critical CSS for ${remoteName}`);
    },
    // Custom deferred style injector (defaults to requestIdleCallback styling)
    deferredInjector: (css, remoteName) => {
        console.log(`Injecting deferred CSS for ${remoteName}`);
    }
});

Remote MFE Registration

A Remote MFE accesses the shared LayoutService from the host and registers its rendering candidates:

// On the remote, when mounting components
import type {LayoutService, CandidateBatch} from "@ly-sys/layout-protocol";

export function mountRemoteComponent(container: HTMLElement, layoutService: LayoutService) {
    // 1. Obtain MFE component's batch output (e.g. from SSR or static rendering)
    const batch: CandidateBatch = {
        candidates: [{utility: "grid-cols-4"}],
        rawCSS: {critical: ".mfe-grid { background: red; }"}
    };

    // 2. Register candidates and critical styles with the Host layout service
    layoutService.registerCandidates(batch, "remote-mfe-auth");

    // 3. Request deferred styles in a non-blocking callback (e.g., in requestIdleCallback)
    layoutService.requestDeferredCSS("remote-mfe-auth");
}

Data Model Specifications

Candidate

Represents an individual layout utility.

type Candidate = {
    utility: string;              // e.g. "flex-row", "gap-4" (always prefix-free)
    breakpoint?: string;          // e.g. "md", "lg", or undefined for the baseline
};

CandidateBatch

The payload containing styling components.

type CandidateBatch = {
    candidates: Candidate[];
    rawCSS?: {
        critical?: string;          // Injected synchronously (render-blocking)
        deferable?: string;         // Injected asynchronously (non-blocking)
    };
};

LayoutService

The interface exposed via Module Federation context:

type LayoutService = {
    readonly engine: LayoutEngineRef;
    registerCandidates(batch: CandidateBatch, remoteName: string): void;
    requestDeferredCSS(remoteName: string): void;
};

License

MIT. See the root LICENSE file.