Appearance
Dependency resolution
A package install touches two distinct dependency surfaces:
- Runtime npm dependencies —
package.json:dependenciesandoptionalDependencies. Resolved vianpm installfrom the configured registry. - Install lifecycle hooks — Matrix-specific scripts the package declares in
matrix.json:install.<phase>. Run after the copy completes.
Runtime npm dependencies
Source: installRuntimeNpmDependencies in packages/mx-cli/src/commands/install.ts:217-291.
For tarball-source installs only (not directory-source), the CLI:
- Reads
package.json:dependenciesandoptionalDependencies. - If both are absent or empty, skips the step entirely.
- Otherwise rewrites the staged
package.jsoninto a private wrapper:json{ "private": true, "name": "mx-runtime-deps-<sanitized-package-name>", "version": "0.0.0", "dependencies": { ... }, "optionalDependencies": { ... } } - Writes a temporary
.npmrcat<tempDir>/.npmrccarrying:- The configured registry as default and as the
@open-matrix:scope override. - The
_authTokenif a credential is found.
- The configured registry as default and as the
- Runs:
npm install \ --omit=dev \ --omit=peer \ --legacy-peer-deps \ --no-audit \ --fund=false \ --package-lock=false \ --userconfig <tempDir>/.npmrc - Restores the original
package.jsonafter npm install completes. - Records a
dependenciesentry in the install'slifecyclePhaseslist.
If npm install fails, the entire install fails and the package is not promoted out of staging.
Why not run this on directory-source installs? Because directory installs typically come from a workspace where the dependencies are already resolved by the workspace package manager (pnpm in this repo). Running npm install again would be redundant and slow.
Install lifecycle hooks
matrix.json:install.<phase>.script declares a JS file the installer runs after the package is copied into place. Validator: packages/mx-cli/src/utils/manifestValidator.ts:44-67.
Phase ordering (install.ts:302-339):
validate → migrate → seed → verifyEach phase is run separately. A non-zero exit code aborts the install and triggers backup restoration.
Each hook receives an environment with these variables set:
| Env var | Meaning |
|---|---|
MATRIX_PACKAGES_DIR | The package store root (<MATRIX_HOME>/packages/...) |
MATRIX_PACKAGE_DIR | The directory the script's package was just installed into |
MATRIX_PACKAGE_NAME | The package name |
MATRIX_PACKAGE_VERSION | The package version |
MATRIX_INSTALL_SOURCE | The original source string passed to mx install |
MATRIX_INSTALL_PHASE | The phase being run (validate/migrate/seed/verify) |
Hooks are invoked with process.execPath <scriptPath>. They run in the package's own working directory.
Phase semantics
| Phase | Convention |
|---|---|
validate | Sanity-check prerequisites the install needs. Refuse to proceed if not met. |
migrate | Migrate previous-version state. Idempotent. |
seed | Lay down initial files, schema, sample data. Skip if already done. |
verify | After everything, confirm the install is healthy. Fail loudly if not. |
These are conventions, not enforced. The CLI runs each script identically; what they do is up to the package.
Workspace-internal dependencies
Workspace dependencies (workspace:* in package.json:dependencies) are resolved by pnpm at install time inside the monorepo. They do not get rewritten into version specifiers when the package is packed; npm pack carries workspace:* through. When the resulting tarball is installed at a remote site, those workspace specifiers become real npm specifiers — the publishing pipeline must handle the substitution before tagging a release. The repo currently does this in packages/hivecast/scripts/publish-bootstrap-packages.js for the HiveCast bootstrap set.
See also
- Installing → Install from registry
- Installing → Install from local folder
- Authoring → Package manifest
- Reference → Manifest schema
Source:
projects/matrix-3/packages/mx-cli/src/commands/install.ts:217-339implements both the npm dependency install and the lifecycle hook runner.