Skip to content

Getting Started โ€‹

Mono-repo is a way to build a large-scale, modular front-end on top of the Vue ecosystem. The goal is a maintainable, clean, complex project that takes minimum effort to grow.

Concept โ€‹

Vue gives every project the same predictable shape:

  • src/pages โ€” routing
  • src/layouts โ€” layouts

Inside a layout you usually find the same generic pieces: Sidebar, Navbar, Login, Logout, Middleware. Every normal website needs them.

Mono-repo makes this simple. Those generic pieces live once in the Host, and every Remote can use them without rebuilding.

A Remote only adds its own modules. It does not re-create Login, Logout, or any of the generic things โ€” the Host already handles all of that.

Because of this modular concept, the Host can have many Remotes, and all of them live inside the Host. Think about a house that have many rooms.

Visual Example โ€‹

One Host owns the shell; each finance module plugs in as its own Remote:

Host โ€” owns the shell of the app.

host/
โ””โ”€โ”€ src/
    โ”œโ”€โ”€ pages/         # login, logout, etc.
    โ”œโ”€โ”€ layouts/       # sidebar, navbar, etc.
    โ””โ”€โ”€ ...etc/

Remote โ€” just adds modules, for example a Budget module.

remote/
โ””โ”€โ”€ src/
    โ”œโ”€โ”€ pages/         # budget module
    โ””โ”€โ”€ ...etc/

Install โ€‹

Both the Host and every Remote are standalone pnpm apps. They install the EJI libraries from a private git repo and pin every dependency through a pnpm workspace catalog โ€” a single pnpm-workspace.yaml that both apps share so their versions never drift. Your package.json then just points at the catalog with catalog:<group>.

Prerequisites โ€‹

  • pnpm (the catalog feature below needs a recent pnpm).
  • A GitHub classic token โ€” the libraries live in the private EJI-ICT/libs repo, so the git URLs are token-authenticated. The snippets below use <GITHUB_CLASSIC_TOKEN> as a placeholder; replace it with your token.

1. pnpm-workspace.yaml โ€‹

This is the single source of truth for versions. The internal catalog pulls the four EJI libraries from git; the other groups pin the dependencies those libraries expect (their peers).

yaml
shellEmulator: true
trustPolicy: no-downgrade
packages: []

catalogs:
  # Internal EJI-ICT libraries (private git repo, token-authenticated)
  internal:
    esw-utils: git+https://<GITHUB_CLASSIC_TOKEN>@github.com/EJI-ICT/libs#path:/packages/esw-utils
    mono-devextreme: git+https://<GITHUB_CLASSIC_TOKEN>@github.com/EJI-ICT/libs#path:/packages/mono-devextreme
    mono-helper: git+https://<GITHUB_CLASSIC_TOKEN>@github.com/EJI-ICT/libs#path:/packages/mono-helper
    mono-utils: git+https://<GITHUB_CLASSIC_TOKEN>@github.com/EJI-ICT/libs#path:/packages/mono-utils

  # Build pipeline: Vite, bundler plugins, OData codegen
  build:
    '@odata2ts/http-client-api': ^0.6.3
    '@odata2ts/odata-query-objects': ^0.28.1
    '@odata2ts/odata-service': ^0.23.1
    '@odata2ts/odata2ts': ^0.40.1
    '@vitejs/plugin-vue': ^6.0.7
    unocss: ^66.7.0
    unplugin-auto-import: ^21.0.0
    unplugin-vue-components: ^32.1.0
    vite: 8.0.16
    vite-plugin-mkcert: ^2.1.0
    vite-plugin-vue-devtools: ^8.1.2
    vite-plugin-vue-layouts: ^0.11.0

  # Dev tooling: type-checking, env helpers, upgrades
  dev:
    '@iconify/json': ^2.2.483
    '@tsconfig/node22': ^22.0.5
    '@vue/tsconfig': ^0.9.1
    dotenv: ^17.4.2
    dotenv-cli: ^11.0.0
    taze: ^19.14.1
    typescript: ~6.0.3
    vue-tsc: ^3.3.3

  # Frontend runtime: shipped to the browser bundle
  frontend:
    '@unhead/vue': 3.1.3
    '@vueuse/core': 14.3.0
    '@vueuse/integrations': 14.3.0
    devextreme: 25.1.6
    devextreme-vue: 25.1.6
    jwt-decode: ^4.0.0
    notivue: ^2.4.5
    pinia: 3.0.4
    universal-cookie: ^8.1.2
    vue: 3.5.24
    vue-router: 5.0.4
    yup: ^1.7.1

  # Type definitions
  types:
    '@types/node': ^25.9.2

onlyBuiltDependencies:
  - esbuild

The Host adds a couple of extras to its frontend/build catalogs (@sentry/vue, @sentry/integrations, @sentry/vite-plugin) for error reporting. A Remote doesn't need them.

2. package.json โ€‹

Reference the catalog with catalog:<group> โ€” pnpm resolves the version from pnpm-workspace.yaml, so you never repeat version numbers per app.

json
{
  "dependencies": {
    "mono-devextreme": "catalog:internal",
    "@unhead/vue": "catalog:frontend",
    "@vueuse/core": "catalog:frontend",
    "@vueuse/integrations": "catalog:frontend",
    "dotenv": "catalog:dev",
    "jwt-decode": "catalog:frontend",
    "notivue": "catalog:frontend",
    "pinia": "catalog:frontend",
    "universal-cookie": "catalog:frontend",
    "vue": "catalog:frontend",
    "vue-router": "catalog:frontend",
    "yup": "catalog:frontend"
  },
  "devDependencies": {
    "esw-utils": "catalog:internal",
    "mono-helper": "catalog:internal",
    "mono-utils": "catalog:internal",
    "@iconify/json": "catalog:dev",
    "@odata2ts/http-client-api": "catalog:build",
    "@odata2ts/odata-query-objects": "catalog:build",
    "@odata2ts/odata-service": "catalog:build",
    "@odata2ts/odata2ts": "catalog:build",
    "@tsconfig/node22": "catalog:dev",
    "@types/node": "catalog:types",
    "@vitejs/plugin-vue": "catalog:build",
    "@vue/tsconfig": "catalog:dev",
    "devextreme": "catalog:frontend",
    "devextreme-vue": "catalog:frontend",
    "dotenv-cli": "catalog:dev",
    "taze": "catalog:dev",
    "typescript": "catalog:dev",
    "unocss": "catalog:build",
    "unplugin-auto-import": "catalog:build",
    "unplugin-vue-components": "catalog:build",
    "vite": "catalog:build",
    "vite-plugin-mkcert": "catalog:build",
    "vite-plugin-vue-devtools": "catalog:build",
    "vite-plugin-vue-layouts": "catalog:build",
    "vue-tsc": "catalog:dev"
  }
}

3. Why these deps โ€” peer dependencies โ€‹

The EJI libraries don't bundle their runtime dependencies; they declare them as peerDependencies. That means your app installs them once โ€” so there's a single copy of vue, vue-router, etc., and you control the versions (via the catalog above). The list above already covers them; here's the full picture so you know what each library expects:

LibraryDeclares as peers (you must provide)
mono-helper(none) โ€” it bundles its own lit + flatpickr, so just install it.
mono-utilsvue, vue-router, jwt-decode, @unhead/vue, dotenv, dotenv-cli, esw-utils, mono-devextreme
esw-utilsvue, vue-router, yup, notivue, @odata2ts/odata-query-objects, @odata2ts/http-client-fetch, json-server, change-case, chokidar

A few esw-utils peers are feature-specific โ€” add them only if you use that feature:

  • json-server โ€” the local mock API for development.
  • change-case, chokidar, @odata2ts/* โ€” OData type generation (see OData Types).

Install everything declared in package.json:

sh
pnpm i

For the UI components and theming, continue with Mono-UI โ†’ Getting started and Theme.