Self-hosted service
namecheap/ilc avatar
namecheap/ilc

namecheap/ilc and the case for server-rendered micro frontends

Enterprise-ready framework for Micro Frontends composition into SPA with SSR & i18n support

775 stars44 forksTypeScriptNOASSERTION

At a glance

What is it?
Isomorphic Layout Composer is a layout service from Namecheap that assembles a page from independently deployed fragment services, renders it on the server, then hands the result to the browser for client-side routing. This is what it gives a team that wants micro frontend autonomy without giving up server-rendered HTML, and what it costs to run.
Who is it for?
Adopt ILC if you run several independently deployed frontend apps and need a server-rendered first paint with client-side routing afterwards, and you can operate a registry service with its own database. Do not adopt it for a single-app product, for a team unwilling to run the registry and the compose stack, or for a public site where the sample configuration of trusted origins set to all is unacceptable.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Isomorphic composition: the server renders first, the browser takes over

The core idea in ILC is a split between two rendering phases. On the first request, the layout service assembles the page on the server from fragment services that support server-side rendering, and the finished document is passed to the client. From that point on, the client-side rendering layer handles all further routing, so subsequent navigations never round-trip through the server the way a traditional server-rendered site would.

The README calls this isomorphic page composition and presents it as the project's competitive advantage over other approaches. The claim is specific and testable in principle: you get server-rendered HTML for the first paint, then the responsiveness of a single-page application once the user starts clicking. The design also explains why ILC ships adapters rather than owning a rendering model of its own. React, Vue.js, and Angular are all supported because the layout service talks to frameworks through the adapter ecosystem rather than through a bespoke component contract.

The trade-off is that the server side and the client side have to agree on the same composition rules, and those rules come from the registry. That makes the registry the real centre of the system, and it is worth looking at it before looking at anything else.

The registry is a separate service with its own database and worker

Configuration for ILC does not live in the layout service. It lives in a separate application, the registry, which holds the list of micro fragments, the routes, and the configuration that the layout service reads while composing a page. The repository is split accordingly into an `ilc` directory with the composer code and a `registry` directory with the configuration store, alongside `docs`, `e2e`, and the demo applications.

The registry is not a read-only table. The README lists a built-in registry as a key feature, with the ability to add new apps and pages, or change configs and templates, without a redeploy of the composer. Underneath, the compose setup runs a second registry process, `registry_worker`, whose command is an asset discovery run:

yaml
    registry_worker:
        image: namecheap/ilc_registry:latest
        command: ['npm', 'run', 'assetsdiscovery']
        environment:
            NODE_ENV: production
            DB_CLIENT: pg
            DB_HOST: postgres
            DB_USER: root
            DB_PASSWORD: pwd
            DB_NAME: ilc

Two processes and a relational database are a real operational cost for a layout service. The environment block above also shows default credentials, which is fine for a laptop and unacceptable anywhere else.

Docker Compose brings up four containers on one shared network

The quick start does not require you to install and wire the services by hand. The README asks for a clone of the repository, a `pnpm install`, and then `docker compose up -d`, which starts the composer, the registry, the registry worker, and a demo-apps container. The compose file publishes port 8233 for the composer itself and 4001 for the registry UI, and maps a range of ports from 8234 to 8240 for the demo applications.

The composer container points at the registry through an environment variable rather than a hardcoded address:

yaml
    ilc:
        image: namecheap/ilc:latest
        restart: always
        ports:
            - '80:8233'
            - '8233:8233'
            - '8234-8240:8234-8240' # Ports from "demo-apps" container
        environment:
            NODE_ENV: production
            REGISTRY_ADDR: 'http://host.docker.internal:4001'
            OVERRIDE_CONFIG_TRUSTED_ORIGINS: all

`OVERRIDE_CONFIG_TRUSTED_ORIGINS: all` is a convenience for local development. It is a value you must change before the stack faces anything but a developer's laptop. The demo applications load their settings from a `demo-apps.env` file in the repository root, which is where you would override the public host for the demo site.

Seeding the registry is a separate step after the containers are up

Starting the stack does not give you a working site. The README makes the next step explicit: run `docker compose run registry npm run seed` and wait for it to finish, then open the composer at http://localhost:8233/ or the registry UI at http://localhost:4001/ with the credentials `root` and `pwd`. The seed step is what populates the configuration the composer needs in order to assemble a page at all.

The output confirms the seed ran against the configuration directory:

bash
    [+] Running 1/1
    > [email protected] seed /codebase
    > knex --knexfile config/knexfile.ts seed:run
    Ran 8 seed files

The database driver is selected by the `DB_CLIENT` variable, and the shipped compose file uses `pg` with a Postgres service, while the quick start notes describe switching the registry and registry worker to `pg` as an optional step if the default is not what you want. Either way, the first run of ILC is a database-first exercise, not a frontend one, and a team without a Postgres or MySQL service available locally will not get as far as the browser.

Node 22 and pnpm 12 set a high floor on the toolchain

The root package.json is explicit about the environment it expects. This is a monorepo managed with pnpm, with a pinned package manager and engine constraints that will refuse to install on older runtimes:

json
    "engines": {
        "node": ">= 22",
        "pnpm": ">= 12"
    },
    "packageManager": "[email protected]"

Requiring Node 22 is a meaningful constraint in corporate environments, where the standard runtime image may still trail by a year or more. The scripts section shows how the pieces are built and started, with `build` filtering both workspaces and `start` launching `start_all.js`; there is also a `start:no-apps` variant for running the composer without the demo applications. Formatting is handled by Prettier across both the `registry` and `ilc` directories, and Husky is wired in through `prepare` with commitlint and lint-staged at the root, so the repository expects conventional commits from contributors.

None of that is unusual for a TypeScript monorepo, but it does mean the project assumes a modern Node toolchain and a package manager that is not npm or yarn.

The README claims about 17ms of server-side overhead, and the release history has a long gap

Two numbers deserve scrutiny. The first is performance. The README states that the server-side part of the system adds just around 17ms of latency. No benchmark methodology, dataset, or measurement setup accompanies that figure, so treat it as a vendor claim about the composer's own overhead rather than as an independent measurement, and measure it in your own deployment before accepting it as a budget line.

The second is cadence. The last push to the default branch was on 2026-10-19, and the repository is not archived, so the code is being touched. Tagged releases tell a different story: version 3.0.0 shipped on 2025-02-06, v2.10.0 on 2022-02-03, and v2.9.0 on 2021-06-07. Recent development is therefore landing on the default branch without a new tag for well over a year, which matters if your upgrade plan is tied to releases. Check what has changed between the 3.0.0 tag and the current branch before assuming an upgrade is a version bump.

Licensing is the third thing to check. The project carries a custom licence that GitHub cannot classify, with the terms in the LICENSE.md file at the repository root, alongside a NOTICE.md file, even though the root package.json declares Apache-2.0 for the monorepo package. Read the actual file before shipping it in a commercial product.

How ILC differs from a client-only shell and from a classic server template

The alternatives to ILC are approaches, not products, and the difference is where rendering happens. A client-only micro frontend shell composes the page in the browser, which keeps the server out of the composition path entirely and makes deployment simple, but the first paint depends on the browser fetching and running every fragment. A classic server-side template renders the whole page on the server, which gives fast first paint and simple caching, but it couples the frontend teams into one codebase and one release cycle, which is exactly the situation the README describes as the common practice it wants to break.

ILC sits between the two and pays for that position with infrastructure: the registry, the database, the worker process, and the requirement that fragments support server-side rendering. Its distinct features, such as parcels, app wrappers, plugins, and internationalization support, extend what a fragment can do rather than changing the composition model. If your fragments are plain client-rendered apps with no SSR support, the isomorphic advantage does not apply to them, and you are left with the operational cost of the registry without the benefit that justifies it.

Editorial conclusion

Adopt ILC if you run several independently deployed frontend apps and need a server-rendered first paint with client-side routing afterwards, and you can operate a registry service with its own database. Do not adopt it for a single-app product, for a team unwilling to run the registry and the compose stack, or for a public site where the sample configuration of trusted origins set to all is unacceptable. Before committing, verify the Node 22 and pnpm 12 floor in the root package.json, check that the 3.0.0 release from 2025-02-06 covers the features you need, and read LICENSE.md, since the project ships a custom licence rather than a standard one.

Frequently asked questions

What is namecheap/ilc and what does it do?

It is the Isomorphic Layout Composer, a layout service that assembles a web page from fragment services and supports client-side and server-side page composition. The server renders first for apps that support server-side rendering, and the client-side rendering layer handles further routing afterwards.

How do I run namecheap/ilc locally?

Clone the repository, run `pnpm install`, then `docker compose up -d`, then seed the registry with `docker compose run registry npm run seed`. The composer is then at http://localhost:8233/ and the registry UI at http://localhost:4001/ with the user `root` and password `pwd`.

Which database does the namecheap/ilc registry use?

The choice is made with the `DB_CLIENT` environment variable in the `registry` and `registry_worker` services. The shipped docker-compose.yml sets `DB_CLIENT: pg` with `DB_HOST: postgres` and `DB_NAME: ilc`, and the quick start describes switching the client to `pg` as an optional step.

Does namecheap/ilc work with React, Vue and Angular?

The project describes itself as technology-agnostic and connects frameworks through the adapters provided in the single-spa ecosystem, with some of the original adapters extended for ILC, including React and Vue.js adapters. The server-side rendering advantage applies only to fragments that support SSR.

What licence does namecheap/ilc use and how active is the project?

The project uses a custom licence that GitHub cannot classify, with the terms in the LICENSE.md file at the repository root, while the root package.json declares Apache-2.0. The repository is not archived and the last push was on 2026-10-19, but the most recent tagged release, 3.0.0, dates from 2025-02-06.

Official sources

  1. Issues
  2. namecheap/ilc on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/namecheap-ilc.svg)](https://hysenlabs.com/projects/namecheap-ilc)

Was this useful?