Skip to content
Back to the blog

Diagnose an npm monorepo: two applications and one shared package

Keep the root, lockfile and sibling packages before building two frontends: a local npm workspaces diagnostic with two dist outputs, a shared SVG and 404s.

  • npm
  • Monorepo
  • React

A React application can import code outside its own folder. In a monorepo, treating apps/app-a as an independent repository can omit the lockfile and a sibling package. Before choosing hosting, check what the complete build needs and which files each application produces.

This diagnostic uses an original MIT example: two React/Vite frontends, Carta del horizonte and Taller de señales, importing @hostbrid-demo/shared. The completed experiment is local. It does not demonstrate delivery on Hostbrid, SSR compatibility, publication by push or the effective Node version of a product build.

Keep the root that defines the workspaces

The root contains package.json, its workspaces declaration and package-lock.json. Applications live in apps/app-a and apps/app-b; the shared package lives in packages/shared. Installing from the complete copy lets npm resolve these related packages. The npm 10 workspaces documentation describes local packages managed from one root; that page corresponds to npm 10.9.9, labelled Legacy.

Distinguish the folder served to a browser from the folder needed for installation and building. You can publish one output without first cutting away the dependencies its build needs. This is not a single React application with one dist: there are two applications, sibling dependencies and two different artefacts.

Build two outputs without mixing their pages

The experiment used Node 22.23.3 and npm 10.9.9. The repository requires Node 22.23.3 and retains React 19.3.0 and Vite 8.3.4 in its lockfile. Run these commands from a new copy and retain the resource revision:

git clone https://github.com/ocentelles/hostbrid-example-monorepo.git
cd hostbrid-example-monorepo
git checkout bb4c01995cea57f56fcc72af8b02e70126edbf80
node --version
npm --version
npm ci
npm run build
npm test

npm run build checks Node and runs builds A and B. To select them separately from the same root, use the scripts npm run build:a and npm run build:b.

Application Output Example routes
A apps/app-a/dist / and /notas/
B apps/app-b/dist / and /materiales/

The Vite build documentation helps you compare your project’s output. Publishing A’s dist does not publish B. Do not combine their two index.html files or deliver node_modules as the static artefact.

Check the shared piece too

Both applications import the illustration from packages/shared/horizon.svg. The example uses a static new URL('./horizon.svg', import.meta.url) reference and preserves an SVG file with assetsInlineLimit: 0. Nine tests verified that both outputs retain its original bytes, as well as the shared marker, titles and resolvable assets.

A question about multiple public directories in a monorepo illustrates this friction when organising assets. It does not establish that you need a plugin or replace checking the files your implementation produces.

What the local experiment rejected

The negative control retained only apps/app-a, omitting the root lockfile and shared package. npm ci exited with code 1 and EUSAGE because the lockfile was missing, before resolving dependencies. This does not show that a broken shared import was the first failure: installation never reached that stage.

The complete copy passed installation, building and nine Node tests. The separate experiment checked eight Chrome cases: each application’s homepage and inner page at 390 and 1280 pixels, DPR 2. The SVG loaded on both homepages; selection state existed only in browser memory and reset on reload. Four HTTP controls returned 404 for missing routes and SVGs, one of each per application.

npm test reproduces the repository’s nine file tests; it does not automatically run those eight Chrome cases. When serving each output, check page identity, direct navigation, reloads, assets and real errors. A 200 with the wrong homepage does not demonstrate a correct route.

Before choosing Projects

The result identifies local dependencies and artefacts. If considering Projects, confirm command compatibility, repository access, available capacity and the effective Node version before purchasing or creating a project. This delivery on the product, public HTTPS, SSR and a backend have not been tested. Keep a separate inventory of services and data; these two dist folders do not move them.

Manage your sites, servers and email.

Forgot your password?

Free, and it takes a minute.

At least 8 characters. Not all digits, not a common one.

We'll email you to confirm the account.