Monorepos
Miso has first-class support for monorepos. When configured, you can run workspace-scoped scripts using the @workspace/script syntax, and Miso will automatically scope commands based on your current directory.
Setup
1. Add "repo": "mono" to miso.json:
{
"repo": "mono"
}2. Add a workspaces field to your root package.json:
{
"name": "my-monorepo",
"packageManager": "pnpm",
"workspaces": [
"apps/*",
"packages/*"
]
}The workspaces field uses standard glob patterns and is compatible with npm, yarn, pnpm, and bun — no extra tooling required.
Workspace Scripts
Each workspace can have its own scripts/ folder. Miso discovers and executes scripts from the correct workspace, and sets the working directory to that workspace’s root so all relative paths resolve correctly.
Folder Structure
my-monorepo/
├── miso.json
├── package.json
├── scripts/ ← root-level scripts
│ └── build.sh
├── apps/
│ ├── api/
│ │ └── scripts/ ← workspace-scoped scripts
│ │ ├── build.sh
│ │ └── deploy.sh
│ └── web/
│ └── scripts/
│ ├── build.sh
│ └── dev.sh
└── packages/
└── ui/
└── scripts/
└── build.shRunning Workspace Scripts
From the Root — @workspace/script Syntax
Target any workspace’s scripts from the project root using the @workspace/script syntax:
miso @api/build # runs apps/api/scripts/build.sh
miso @web/dev # runs apps/web/scripts/dev.sh
miso @ui/build # runs packages/ui/scripts/build.shThe workspace identifier is the part between @ and the final /. By default this is the basename of the workspace directory — for example, apps/api → api, packages/ui → ui.
From Inside a Workspace — Automatic Scoping
When you’re already inside a workspace directory, Miso automatically scopes to that workspace. No special syntax needed:
cd apps/api
miso build # resolves to apps/api/scripts/build.sh
miso deploy # resolves to apps/api/scripts/deploy.shThis matches the same behaviour you’d expect from tools like Turborepo’s automatic package scoping.
How Workspace Matching Works
The identifier in @identifier/script is matched against every discovered workspace using three strategies, checked in order:
- Basename — the final segment of the workspace directory path (e.g.
apimatchespackages/api) - Relative path from root — the full path from the repo root (e.g.
packages/apimatchespackages/api) package.jsonname — thenamefield in the workspace’spackage.json(e.g.@myorg/api)
So for a workspace at packages/api with "name": "@myorg/api" in its package.json, all three of the following are equivalent:
miso @api/build # matched by basename
miso @packages/api/build # matched by relative path
miso @myorg/api/build # matched by package.json nameIf the identifier matches more than one workspace, Miso exits with an error listing the conflicting paths so you can use a more specific form:
workspace "api" is ambiguous — matches multiple workspaces: apps/api, packages/api (use a more specific identifier)If no workspace matches, Miso exits with an error listing the available workspace names:
workspace "typo" not found (available: api, web, ui)