Skip to content

Vue · Nuxt · Web components

Mono — build Vue and Nuxt apps as micro-frontend

One Host owns the shell. Every module plugs in and develops on its own. Shared UI, cookies, JWT, configs. Making the app modular, composable, and maintainable.

Host module composing nested modules A Host Module on the left, with its repository path. It composes Module One, Module Two, Module Three and a Module Group, each with its own repository and a deploy status: Module One is in development, Module Two is failing, and Module Three and the Module Group are deployed. The Module Group nests one level deeper, holding Module Four, Module Five and Module Six. Host Modulegithub.com/company/hostModule Onegithub.com/company/module-oneModule Twogithub.com/company/module-twoModule Threegithub.com/company/module-threeModule Groupgithub.com/company/module-groupModule FourModule FiveModule Six

Minimize the conflict surface of every module

In a monolith every feature lands in the same tree, and every branch has to get back onto the same main. Two of these five make it. The other three touch the files everyone touches, and stop.

MonolithOne repository, five developers, one main
Five branches off one main, and only two of them land A git graph. Five developers share a single repository, github.com/company/app, holding src/router.ts, src/store.ts, package.json and 1,240 more files. A long main branch runs across the top. Five branches leave it in turn: chore/deps, feat/billing, feat/orders, fix/auth and feat/report, each raising a merge request. chore/deps and feat/billing curve back into main and land as merge commits. The remaining three — feat/orders, fix/auth and feat/report — all touch the same three shared files, so none of them can rejoin: their branches stop dead and are marked as conflicts, while main carries on ahead without them. Monolithsrc/router.tssrc/store.tspackage.json+ 1,240 moregithub.com/company/appmainchore/depsMR #16feat/billingMR #13feat/ordersMR #12fix/authMR #14feat/reportMR #15Merge conflictsrc/router.tssrc/store.tspackage.json3 of 5 branches blocked

In a Mono-Repo, the modular approach minimizes the conflict down to a single developer. You want to take over a specific module? That's fine — the others still run, even in parallel.

Mono-Repo One repository per developer, all wired into a single Host
Four developers, four repositories, one Host — and one of them unplugged Four developers, each owning one module in a repository of their own, all feeding a single Host Module at github.com/company/host that owns the shell and is managed by one person of its own. Module One is deployed with a warning. Module Two has been taken over: its developer is still attached to it, but its wire into the Host is gone entirely and its card is marked with an error, so it is not currently wired in at all. Module Three is clean. Module Group is clean too, and holds Module Four, Module Five and Module Six inside it. The three modules that are still wired keep running throughout, unaffected by the one pulled out. Module One github.com/company/module-oneModule Two github.com/company/module-twoModule Three github.com/company/module-threeModule Group github.com/company/module-groupModule FourModule FiveModule SixHost Modulegithub.com/company/hostowns the shellone owner

Basic UI to centralize, everyone just uses the single UI library.

Built on top of Lit Web Components, can be used anywhere and anytime. Fully general and basic components, can be easily customized to your own style.

Need Cookie and JWT across your ecosystem?

We cover it — define it inside our mono.config.ts, used anywhere across your ecosystem.

What else? Data fetching, even with OData fetching.

One fetcher for plain REST, one for OData — same call shape, same config, same auth. Press Run: these hit live public APIs from this page.

Behind the config, the sync between apps happens.

You just need to configure it in one config. Declare each app once, run pnpm mono:sync, and every one of them lands in .mono/apps/ — no git submodules to babysit.

apps says what to clone; extends says what is switched on. Take a whole module, take only its components, or comment it out and it stays cloned but wired to nothing.

Need an AI agent to explore the mono ecosystem? Use llms.txt every time you want to prompt something.

llms.txt helps an AI agent explore the documentation from its markdown version. Usually an agent goes to the web and reads the whole HTML — this time the agent only reads completely readable text.

Example prompt
Read https://mono-libs.netlify.app/llms.txt first, then open the
Table, DataSource and Config pages it lists.

In my Vue Remote, build a User master page:

- src/pages/master/user.vue
- controlMonoTable<UserRow> with keyExpr 'UserName' and
  searchValue ['UserName', 'FirstName', 'LastName']
- feed it from the myOdata entry in mono.config.ts using
  monoCreateFetcher, so search, sort and paging all run
  server-side
- columns: UserName, FirstName, LastName, Gender
- <mono-table-search> in the toolbar, <mono-table-paging>
  underneath at 25 rows per page, <mono-table-loading>
  inside the table
- register it in menu[] as { title: 'User', url:
  '/master/user', icon: 'i-mdi-account-group' } so the
  Host picks it up