OpenComponents monorepo: a micro-frontends project rebuilt on npm workspaces and Turborepo
OpenComponents, serverless in the front-end world for painless micro-frontends delivery
At a glance
- What is it?
- The oc repository is the OpenComponents project, described as serverless in the front-end world for painless micro-frontends delivery, and it has recently been reorganised as an npm workspaces monorepo with Turborepo and Changesets. The root holds four packages: the oc package itself, a browser client, a metadata adapter utilities package, and an Azure SQL metadata adapter.
- Who is it for?
- The oc monorepo fits a team delivering independently deployable UI components over HTTP and wanting the packaging, versioning, and release discipline of a modern JavaScript workspace. It is the wrong thing to adopt for a single component library, since the workspace machinery only pays off once several packages move independently.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on November 8, 2026, and from our analysis. They are not legal advice.
Star history
- opencomponents/oc1,473 β Β· +1
| Repository | 2026-10-16 | 2026-11-08 |
|---|---|---|
| opencomponents/oc | 1.5k | 1.5k |
1 Stars in the last 23 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
What the project is, in one line
The repository description is compact: OpenComponents, serverless in the front-end world for painless micro-frontends delivery. The topic list fills in the vocabulary, with components, continuous-delivery, microfrontends, opencomponents, serverless, and ui-composition.
Those topics together describe a specific architectural idea. A micro-frontends setup splits a large front end into independently built and independently deployed pieces, and the hard part is not the splitting, it is the delivery. If a team owns five separate applications and wants a consistent look and shared behaviour across them, the options are a shared library, which forces a coordinated release, or a shared service, which turns every component into a network dependency with a runtime bill. OpenComponents takes the service route, and the serverless framing is the mechanism: the components are served rather than bundled, and the host application loads them over HTTP.
That has consequences in both directions. The upside is that a component can be updated without rebuilding the host, and a host application can adopt a component without a version negotiation with every other team. The downside is that the component is now a remote dependency, so a failure in the component service affects every page that uses it, and the host application has to deal with loading states, versioning, and a component that can change under it.
The primary language is JavaScript, the licence is MIT, and the homepage is at opencomponents.github.io. The last push to the repository was on 2026-10-18, so the work is current.
The monorepo has four packages and a documented shape
The project summary is short because the project summary is now about the monorepo rather than the framework. It states that the repository is set up as a monorepo foundation using npm workspaces, Turborepo and Changesets, and lists the current workspace packages: `packages/oc`, the existing oc package, `packages/oc-client-browser`, `packages/oc-metadata-adapters-utils`, and `packages/oc-azure-sql-metadata-adapter`.
The directory tree is given explicitly, which is unusual and useful, because it shows both the workspace layout and the shape of the main package:
.
βββ .changeset/
βββ package.json # monorepo root scripts (turbo + changesets)
βββ turbo.json # task pipeline
βββ packages/
βββ oc/
β βββ package.json
β βββ src/
β βββ test/
β βββ tasks/
βββ oc-client-browser/
βββ oc-metadata-adapters-utils/
βββ oc-azure-sql-metadata-adapter/Two things in that tree carry weight. The `oc` package has its own `test/` and `tasks/` directories alongside `src/`, which is the shape of a package that has both a test suite and its own build tasks, and the `tasks/` directory suggests those build steps are defined per package and orchestrated from the root rather than duplicated in every package.
The four package names also describe an architecture. The `oc` package is the core. `oc-client-browser` is the browser client. The two adapter packages are a utilities package and a concrete implementation for Azure SQL, which is the pattern of a shared adapter interface with pluggable backends, and it tells you the metadata layer is pluggable rather than hard-coded to one store.
A `V1.md` file at the root suggests a version one of the project is being documented or planned alongside the current one, which is a detail worth checking before you read the code, since a monorepo that has just been restructured is the moment when the boundaries are still moving.
Changesets and Turborepo are the release machinery
The common commands section of the project summary is the most practically useful part of it, because it is the whole developer workflow in six lines.
`npm run lint` runs lint across the workspaces via Turbo. `npm run build` builds all workspaces. `npm run test` and `npm run test-silent` run the test pipelines. `npm run changeset:status` shows pending release bumps. `npm run release:prepare` runs the tests and applies pending changesets. `npm run release:publish` builds and publishes the pending package releases.
The `changeset:status` command is the one that shows the philosophy. A changeset is a small file, added to the `.changeset/` directory, that describes one change and which packages it affects. `changeset version` reads those files, works out the semver bump for each affected package, updates the manifests and the changelogs, and consumes the files. `changeset publish` then pushes the published versions and tags them.
The effect is that a contributor never edits a version number. They describe what they changed, and the tooling decides whether it is a patch, a minor, or a major, and applies it to exactly the packages affected. In a monorepo with four packages that move at different rates, that is the difference between a coordinated release dance and a pull request that just adds a file.
The `release:prepare` script is `npm run test-silent && npm run changeset:version`, and `release:publish` is `npm run build && changeset publish && changeset tag`. The full `release` script chains the two. So the release path is test, then version, then build, then publish and tag, with the test running before anything is published and the build running before the publish, which is the order you want.
The root package.json makes the same structure explicit in code. The package is named `oc-monorepo` and is private, with the workspaces set to `packages/*`, and the scripts delegate to `turbo run` for build, test, test-silent, and lint. The `preview` script is scoped to a single package with `turbo run preview --filter=oc`, which is the useful trick for a monorepo where you want the dev server for one package without the noise of the others. The dev dependencies are just three, `@changesets/cli`, `lefthook`, and `turbo`.
Biome, lefthook, and the rest of the toolchain
The root files show a project that has consolidated its tooling recently and without much nostalgia.
`biome.json` is the linter and formatter configuration. Biome is a single tool that does both linting and formatting in Rust, and replacing an ESLint plus Prettier pairing with it is one of the more common modernisation moves in a JavaScript monorepo, because two tools that both read and write the same files have to be kept in agreement with each other, and one tool cannot disagree with itself.
`lefthook.yml` is the git hooks configuration, and the root package.json runs `lefthook install` in the `prepare` script, which is the npm lifecycle hook that runs on install. Lefthook is a hooks manager written in Go, and it is worth noting that the older alternatives in this space are typically implemented as shell scripts, which is what makes a Go implementation attractive: the hooks behave the same on macOS, Linux, and Windows, where a shell script does not.
The rest of the root has the usual supporting cast. There is a `dependencies.yml`, which in a repository with a `dependencies.yml` is usually the file a bot reads to keep dependency versions aligned across the workspace packages, and that is the kind of automation that becomes necessary once several packages share a large dependency set. There is a `tsconfig.json` at the root for shared TypeScript configuration, an `.nvmrc` pinning the Node version, `.editorconfig` for editor settings, and `.npmignore` and `.gitignore`.
The `packages/` directory has the four workspaces, and the project summary points to per-package documentation: the package docs at `packages/oc/README.md`, the Azure SQL metadata adapter docs at `packages/oc-azure-sql-metadata-adapter/README.md`, and the package changelog at `packages/oc/CHANGELOG.md`. The root also has a `CHANGELOG.md`, and a `CONTRIBUTING.md` that the summary simply points to.
The homepage is opencomponents.github.io, and the packageManager field pins `[email protected]`, so the npm version is part of the contract with the team rather than something a contributor chooses.
Why a micro-frontends project needs a serverless delivery model
It is worth being explicit about the problem this project is solving, because the answer is unusual and the alternatives are well known.
The standard way to share a UI component across several applications is a package. A shared component library is versioned, published, and installed, and the problem is the release train. Every consumer has to take a dependency update, and because the components are usually coupled, one update often means upgrading several. The result in large organisations is a fork of the shared library inside each application, and the shared library stops being shared.
The other standard way is a design system with a build step, where the consumer rebuilds to pick up changes. That has the same coupling with an extra build cost, and it still means the version in production is whatever was built at deploy time.
Serving the component over HTTP removes the version negotiation. The host application asks for a component by name, or by version, or by tag, and gets markup and behaviour. A team can change the component and the change is live, without a rebuild of any consumer, and without a coordinated upgrade window. The topics list continuous-delivery alongside microfrontends, which is the point: the component is deployed continuously rather than released.
The word serverless in the description is doing specific work. It means the delivery layer is a function or a service that scales to zero and is invoked per request, so a component that nobody is using costs nothing, and a burst of traffic is not a capacity problem you have to plan for. That is what makes per-request component delivery economically viable, where the alternative, a long-lived rendering service per component, would have a fixed cost per component whether or not it is used.
What you get in exchange is a runtime dependency. The host application now waits on a network call to render part of its page, and the component can change without notice, which means the contract between host and component is a behavioural one rather than a versioned one. That is a real trade, and it is the reason the metadata adapter split and the browser client package are separate pieces rather than one bundle.
Where this repository is the wrong place to look
The limits are worth stating, and they come mostly from the recency of the restructuring.
First, the monorepo is new and the documentation has not caught up. The project summary is a monorepo README, not a framework README. There is no description here of the component format, the API surface, the client contract, or how a host application declares what it needs. The summary points you at `packages/oc/README.md` for that. So if you are evaluating the project as a user rather than as a contributor, the information you need is one level down, and the root README will not answer your questions.
Second, four packages with independent Changesets versioning is a lot of moving parts for a component delivery system. The advantage is that a package can move at its own pace, and the cost is that you now have to reason about which version of the client a given host is talking to, across packages that the tooling releases separately. A single package with a single version is simpler, and for a project with one consumer it is the right choice.
Third, the whole approach depends on a delivery service existing somewhere. The repository is the library and the client; the serving side, whatever runs the components, is a deployment concern that the project summary does not cover. That is not a criticism, it is a scope statement, but it does mean the repository alone does not give you a working micro-frontends setup.
Fourth, a component fetched at runtime changes the failure model of the host application. A page that depends on a remote component is a page whose content depends on a service being up and on that service returning something the client can render. That is a genuine design decision with real consequences for availability, and it is worth thinking through before you adopt the model, independent of how well this particular implementation does it.
Fifth, and the practical one, this is a JavaScript project with a JavaScript primary language and a Vite-era toolchain, but the `oc` package being TypeScript-flavoured is worth verifying against the specific package you need, since the root `tsconfig.json` suggests the workspace is TypeScript while the language recorded for the repository is JavaScript. If you are integrating the client into a TypeScript application, the type declarations in the package you actually use are the thing to check.
Editorial conclusion
The oc monorepo fits a team delivering independently deployable UI components over HTTP and wanting the packaging, versioning, and release discipline of a modern JavaScript workspace. It is the wrong thing to adopt for a single component library, since the workspace machinery only pays off once several packages move independently. Check three things before you depend on it: that the component delivery model matches what you actually need, since the project describes itself as serverless in the front-end world for painless micro-frontends delivery, that you are comfortable with Changesets driven versioning, where a version bump comes from a changeset file rather than from editing a manifest, and that the package you need is one of the four in the tree, because the split into oc, the browser client, the adapter utilities, and the Azure SQL adapter is recent and the boundaries may still be settling.
Frequently asked questions
What is OpenComponents and what problem does it solve?
It is described as serverless in the front-end world for painless micro-frontends delivery, with the repository topics covering components, continuous delivery, microfrontends, serverless, and UI composition. The idea is to deliver UI components over HTTP so that a component can be updated continuously without rebuilding every application that uses it.
Which packages are in the oc monorepo?
Four workspaces: `packages/oc`, which is the existing oc package, `packages/oc-client-browser`, `packages/oc-metadata-adapters-utils`, and `packages/oc-azure-sql-metadata-adapter`. The oc package itself has a src, test, and tasks directory alongside its package.json.
How are releases versioned in the oc monorepo?
With Changesets. A contributor adds a changeset describing the change and the affected packages, `npm run changeset:status` shows pending release bumps, `npm run release:prepare` runs the tests and applies the changesets, and `npm run release:publish` builds and publishes the pending package releases and tags them.
What are the common commands in the oc monorepo?
From the repository root, `npm run lint` runs lint across the workspaces via Turbo, `npm run build` builds all workspaces, `npm run test` and `npm run test-silent` run the test pipelines, `npm run changeset:status` shows pending release bumps, `npm run release:prepare` tests and applies pending changesets, and `npm run release:publish` builds and publishes them.
Official sources
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.
[](https://hysenlabs.com/projects/opencomponents-oc)Star history chart for your README
[](https://hysenlabs.com/projects/opencomponents-oc)Was this useful?