{"id":15902749,"url":"https://github.com/ctrlplusb/monilla","last_synced_at":"2025-04-02T20:14:03.030Z","repository":{"id":39537925,"uuid":"491347378","full_name":"ctrlplusb/monilla","owner":"ctrlplusb","description":"A CLI to manage monorepos with predictability and stability.","archived":false,"fork":false,"pushed_at":"2022-06-29T10:44:23.000Z","size":442,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-03-20T06:35:18.755Z","etag":null,"topics":["cli","developer-experience","javascript","monorepo","nodejs","tooling","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ctrlplusb.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-05-12T03:14:15.000Z","updated_at":"2023-03-24T05:40:51.000Z","dependencies_parsed_at":"2022-07-04T10:42:35.640Z","dependency_job_id":null,"html_url":"https://github.com/ctrlplusb/monilla","commit_stats":null,"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ctrlplusb%2Fmonilla","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ctrlplusb%2Fmonilla/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ctrlplusb%2Fmonilla/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ctrlplusb%2Fmonilla/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ctrlplusb","download_url":"https://codeload.github.com/ctrlplusb/monilla/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246884767,"owners_count":20849554,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","developer-experience","javascript","monorepo","nodejs","tooling","typescript"],"created_at":"2024-10-06T11:42:55.964Z","updated_at":"2025-04-02T20:14:03.002Z","avatar_url":"https://github.com/ctrlplusb.png","language":"TypeScript","readme":"# Monilla (✨ work in progress ✨)\n\nA CLI to manage monorepos with predictability and stability.\n\n\u0026nbsp;\n\n---\n\n\u0026nbsp;\n\n- [1. Introduction](#1-introduction)\n- [2. Motivation](#2-motivation)\n- [3. Prerequisites](#3-prerequisites)\n- [4. Install](#4-install)\n- [5. Requirements](#5-requirements)\n- [6. Guide](#6-guide)\n  - [6.1. Installing your dependencies](#61-installing-your-dependencies)\n  - [6.2. Linking packages](#62-linking-packages)\n  - [6.3. Updating linked packages](#63-updating-linked-packages)\n  - [6.4. Watching updates to linked packages](#64-watching-updates-to-linked-packages)\n  - [6.5. Upgrading package dependencies](#65-upgrading-package-dependencies)\n- [7. CLI Reference](#7-cli-reference)\n  - [7.1. `clean`](#71-clean)\n  - [7.2. `install`](#72-install)\n  - [7.3. `link`](#73-link)\n  - [7.4. `refresh`](#74-refresh)\n  - [7.5. `watch`](#75-watch)\n  - [7.6. `upgrade`](#76-upgrade)\n- [8. Appreciation](#8-appreciation)\n- [9. Further Reading / References](#9-further-reading--references)\n\n\u0026nbsp;\n\n---\n\n## 1. Introduction\n\nMonilla is a CLI tool which improves the development experience against `npm`-based [monorepos](https://monorepo.tools).\n\nIt avoids the use of workspaces or hoisting, treating each of your monorepo packages as though they were independent packages. We find that this approach increases the predictability and stability of packages within your monorepo. Dependency updates to one package should not affect another.\n\nWe lean heavily into a \"standard\" npm experience and promote the capability for packages to be easily lifted in or out of your monorepo.\n\n- Install dependencies across your monorepo, and link internal packages;\n  ```bash\n  monilla install\n  ```\n- Declare a link between internal packages;\n  ```bash\n  monilla link --from @my/components --to @my/ui\n  ```\n- Perform interactive dependency upgrades across your monorepo;\n  ```bash\n  monilla upgrade\n  ```\n- Watch your packages for changes, updated linked packages;\n  ```bash\n  monilla watch\n  ```\n\n\u0026nbsp;\n\n---\n\n## 2. Motivation\n\n_Coming soon_\n\n\u0026nbsp;\n\n---\n\n## 3. Prerequisites\n\n**Node.js** version 18 or higher is required to use this CLI.\n\n\u003e **Note**\n\u003e\n\u003e There was a change in behaviour between npm versions in how linked package dependencies were installed. A flag (`--install-links`) was introduced to the npm CLI to address this issue.\n\u003e\n\u003e Node 18 by default ships with a version of npm which includes support for this flag. Therefore we are making it a requirement that you utilise Node 18.\n\nWe highly recommend installing [nvm](https://github.com/nvm-sh/nvm) on your machine. It enables you to manage multiple versions of Node.js seamlessly. Utilising `nvm` you can install the required version of Node.js via the following command;\n\n```bash\nnvm install --default 18\n```\n\n\u003e **Note**\n\u003e\n\u003e The `--default` flag will make this installation the default version on your machine.\n\n\u0026nbsp;\n\n---\n\n## 4. Install\n\nWe recommend installing monilla as a dev dependency in the root of your monorepo;\n\n```bash\nnpm install monilla --save-dev\n```\n\n\u0026nbsp;\n\n---\n\n## 5. Requirements\n\n**Linked Packages `package.json` Design**\n\nWe expect that each package within your monorepo is built almost as if it were independent package, that _could_ be published to npm.\n\nThis means that you need to;\n\n- add all the expected dependencies to your `package.json` to meet your package's needs;\n- define the `main` _or_ `exports` _or_ `module` fields to indicate the entries and available imports from your package;\n- define the `files` list, declaring which dirs/files should be exposed by your package;\n\nFor e.g.\n\n```json\n{\n  \"name\": \"@my/stuff\",\n  \"version\": \"0.0.0\",\n  \"private\": true,\n  \"type\": \"module\",\n  \"exports\": \"./dist/index.js\",\n  \"types\": \"./dist/index.d.ts\",\n  \"files\": [\"dist\"],\n  \"scripts\": {\n    \"build\": \"tsup\"\n  },\n  \"dependencies\": {\n    \"chalk\": \"^5.0.1\"\n  },\n  \"devDependencies\": {\n    \"@types/node\": \"^16.11.41\",\n    \"tsup\": \"^6.1.2\",\n    \"typescript\": \"^4.7.4\"\n  }\n}\n```\n\n\u003e **Note**\n\u003e\n\u003e We declare our package as \"private\" with a version of \"0.0.0\". This is intentional as we never intend to actually publish our package to npm. It will only be used by other packages within the monorepo.\n\nWe will perform an \"npm pack\" of your linked packages, carrying across the expected files that would have been exposed if it were published to npm.\n\nThis enables us to produce an `npm install` behaviour for your linked packages that is essentially the same as a vanilla install should the package have been downloaded from the npm registry.\n\n\u0026nbsp;\n\n---\n\n## 6. Guide\n\nImagine a monorepo with the following structure:\n\n```\nmy-mono-repo\n|\n|- apps\n|  |\n|  |- @my/mobile-app\n|     |- src\n|     |  |- index.js\n|     |- package.json\n|\n|- packages\n|  |\n|  |- @my/components\n|     |- src\n|     |  |- index.js\n|     |- package.json\n|\n|- package.json\n```\n\nUsing this as a reference, we'll describe a few scenarios below.\n\n\u003e **Note**\n\u003e\n\u003e All of the below commands should be executed at the root of your monorepo.\n\u003e\n\u003e We have prefixed the commands with `npx` which enables you to quickly\n\u003e execute your local installation of the Monilla CLI.\n\n\u0026nbsp;\n\n### 6.1. Installing your dependencies\n\n```bash\nnpx monilla install\n```\n\nThis performs two functions;\n\n- Installs the required dependencies for each package within the monorepo, including the root\n- Ensures that any linked packages within the monorepo are bound\n\n\u0026nbsp;\n\n### 6.2. Linking packages\n\nLinking enables you to utilise one of your monorepo packages within another as though it were installed via the NPM registry.\n\nThe example monorepo contains a mobile app, and a components library. If we wished to utilise the components library within the mobile app we can link the package.\n\nYou can do so by running the `link` command within the root of your monorepo;\n\n```bash\nnpx monilla link --from @my/components --to @my/mobile-app\n```\n\n\u003e **Note**\n\u003e\n\u003e Monilla will throw an error if you create a circular dependency between your packages.\n\n\u003e **Note**\n\u003e\n\u003e If the source package has a `build` script we will execute it prior to link, ensuring that all the required source files are available.\n\n\u0026nbsp;\n\n### 6.3. Updating linked packages\n\nIf you've performed updates to one of your linked packages, you can ensure that all dependants are using the latest version of them via the following command;\n\n```bash\nnpx monilla refresh\n```\n\n\u003e **Note**\n\u003e\n\u003e If your linked package has a `build` script it will be executed prior to performing the refresh.\n\n\u0026nbsp;\n\n### 6.4. Watching updates to linked packages\n\nWatching your linked packages results in automatic building and pushing of the updates;\n\n```bash\nnpx monilla watch\n```\n\nThis command is especially useful when performing local development across your monorepo.\n\n\u003e **Note**\n\u003e\n\u003e We utilise your `.gitignore` file to determine which files to ignore when executing this process.\n\n\u0026nbsp;\n\n### 6.5. Upgrading package dependencies\n\nWe support interactive upgrading of the dependencies for all the packages within your monorepo;\n\n```bash\nnpx monilla upgrade\n```\n\nYou'll be asked which packages you'd like to update for each of the packages within your monorepo. After this has completed we'll take care of the installs and refreshing of your linked packages.\n\n\u003e **Note**\n\u003e\n\u003e The command has additional flags allowing you to select the type of upgrades you wish to consider. By default we will only look for patch or minor updates for existing dependencies.\n\n\u0026nbsp;\n\n---\n\n## 7. CLI Reference\n\nWork in progress. You can get help via the CLI `--help` flag;\n\n```bash\nnpx monilla --help\n```\n\n### 7.1. `clean`\n\n```bash\nnpx monilla clean\n```\n\nRemoves all `node_modules` folders and `package-lock.json` files from across the monorepo. Supports the good old \"nuke and retry\" strategy when in dire need.\n\n### 7.2. `install`\n\n```bash\nnpx monilla install\n```\n\nThis performs two functions;\n\n- Installs the dependencies for every package, including the root.\n- Ensures that any linked packages are bound.\n\n### 7.3. `link`\n\n```bash\nnpx monilla link --from @my/components --to @my/mobile-app\n```\n\nLink monorepo packages, declaring the `from` package as a dependency within the `to` package.\n\n### 7.4. `refresh`\n\n```bash\nnpx monilla refresh\n```\n\nEnsures that packages are using the latest form of their internal packages dependencies that have been linked against them.\n\n### 7.5. `watch`\n\n```bash\nnpx monilla watch\n```\n\nStarts a \"development\" process that will watch your linked packages for any changes, and will automatically update consuming packages to use the updated versions.\n\n### 7.6. `upgrade`\n\n```bash\nnpx monilla upgrade\n```\n\nPerform an interactive upgrade of the dependencies for all the packages within your monorepo.\n\n\u0026nbsp;\n\n---\n\n## 8. Appreciation\n\nA huge thank you goes to [@wclr](https://github.com/wclr) for the outstanding work on [Yalc](https://github.com/wclr/yalc). The Yalc workflow is the specific seed which enabled this idea to grow. 🌻\n\nAn additional thank you is extended to [@raineorshine](https://github.com/raineorshine) for the amazing work on [`npm-check-update`](https://github.com/raineorshine/npm-check-updates). Updating dependencies would be too laborious without this amazing tool. We couldn't have done it better ourselves, so we have incorporated `npm-check-update` directly. ☀️\n\n\u0026nbsp;\n\n---\n\n## 9. Further Reading / References\n\n- [monorepo.tools - Everything you need to know about monorepos, and the tools to build them.](https://monorepo.tools/)\n- [An abbreviated history of JavaScript package managers](https://javascript.plainenglish.io/an-abbreviated-history-of-javascript-package-managers-f9797be7cf0e)\n- [Exploring workspaces and other advanced package manager features](https://blog.logrocket.com/exploring-workspaces-other-advanced-package-manager-features/)\n- [Inside the pain of monorepos and hoisting](https://www.jonathancreamer.com/inside-the-pain-of-monorepos-and-hoisting/)\n- [The Hoisting Madness in Monorepos](https://enrq.me/dev/2020/04/04/hoisting-in-monorepos/)\n- [Monorepos will ruin your life -- but they're worth it!](https://thenable.io/monorepos-will-ruin-your-life-but-theyre-worth-it)\n- [nohoist in Workspaces](https://classic.yarnpkg.com/blog/2018/02/15/nohoist/)\n- [Tweet from Dan Abramov](https://twitter.com/dan_abramov/status/951931842273398784?lang=en)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fctrlplusb%2Fmonilla","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fctrlplusb%2Fmonilla","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fctrlplusb%2Fmonilla/lists"}