Packages
zlow install reads the package.json you already have and fills node_modules. Compiling stays on the TypeScript page.
How it fits
zlow does two different jobs for TypeScript. The compiler turns .ts files into JavaScript: build, check, bundle, and declarations. The package manager downloads the libraries those files import and puts them on disk.
Installing zlow itself is npm install @zlow/cli. After that command exists, zlow install inside a project installs that project’s dependencies.
zlow install does not type-check. When you want types, run zlow check on its own.
Install dependencies
From the project folder:
zlow install
zlow install --ignore-scriptszlow looks upward from the current directory for package.json. If a parent folder lists this directory in workspaces, that parent is the project root.
The first successful install writes zlow.lock next to package.json. Commit that file. Later installs repeat it, so the same project gets the same versions.
Where the versions come from:
zlow.lockis already there. Those versions are installed.- There is no
zlow.lock, andpackage-lock.jsonis an npm lock version 2 or 3. zlow copies that lock intozlow.lockand installs it.package-lock.jsonis left unchanged. - There is no lock yet. zlow chooses versions that fit the ranges in
package.json, then writeszlow.lock.
Downloads come from https://registry.npmjs.org. Pass --registry to use another registry for this one command. zlow does not rewrite .npmrc.
Every package is checked against its sha512 checksum before it is kept. The bytes live in a cache on your machine: ~/.cache/zlow/store, or $XDG_CACHE_HOME/zlow/store when that variable is set. node_modules links to those cached copies, in the layout Node already walks. Removing a dependency from the project drops the link. The cached copy stays, so the next install can reuse it.
If a download fails, package.json, zlow.lock, and node_modules stay as they were.
Add and remove
zlow add left-pad@1.3.0
zlow add --dev typescript@5.9.2
zlow remove left-padadd updates package.json, zlow.lock, and node_modules together. --dev records the package under devDependencies. remove drops that direct dependency. A package that another installed package still needs stays on disk.
If the download fails, the previous manifest, lock, and tree are left in place.
Install again
zlow install
zlow install --offline
zlow install --productionA later zlow install repeats the lock. It does not go looking for newer versions on its own.
--offline uses the cache only. If a required package is missing from the cache, install stops with error[pm.offline_miss].
--production leaves devDependencies out of node_modules. The lock still lists them. zlow prints dependencies: production (dev omitted).
Edit a range in package.json so the locked version no longer fits, and install stops with error[pm.lock_stale]. It does not quietly pick a replacement. Change the lock with zlow add when you want a new version.
If zlow.lock and package-lock.json disagree about a package, install stops with error[pm.lock_disagreement] and names that package. Fix one of the files yourself. zlow will not choose a side.
Scripts
zlow run test
zlow run test -- --watch
zlow install --ignore-scriptszlow run runs a script named in package.json. Anything after -- is passed through to that script. A missing name is error[pm.script_missing].
During install, zlow also runs preinstall, install, and postinstall from your project and from the packages it just installed. Each script runs in its own folder, through sh, with node_modules/.bin on PATH. node has to be installed for those scripts. If it is not, install stops with error[pm.script_host_missing].
zlow does not run npm, npx, yarn, pnpm, or bun. --ignore-scripts skips lifecycle scripts and prints scripts: skipped (--ignore-scripts).
Workspaces
A root package.json can name the folders that belong to one install:
{
"workspaces": ["packages/*"]
}zlow install at that root links each member into node_modules. If @app/a depends on @app/b with workspace:*, that name points at packages/b in the repo, the sources you are editing. Members can depend on each other in a cycle.
One command
zlow exec prettierzlow exec runs a package’s command from the cache. package.json and zlow.lock are not modified. --offline uses the cache, and stops with error[pm.offline_miss] when the package is not there yet.
Publish
zlow publish
zlow publish --workspace @app/azlow publish uploads the package to the registry. package.json needs a name and a version, and you need a token in NPM_TOKEN or in .npmrc. The token is never printed. If any of those is missing, nothing is sent, and zlow reports error[pm.publish_incomplete].
Publishing a version the registry already has stops with error[pm.version_exists].
--workspace @app/a uploads that one member. A workspace: dependency is rewritten to a normal version range in the upload. The package.json on disk still says workspace:.
Limits
These dependencies are refused before anything is downloaded:
- Git and GitHub dependencies
- An
httporhttpsarchive URL - An
npm:alias that renames another package overrides,resolutions, andpatchedDependencies- A
file:dependency that points outside the project - A
package-lock.jsonthat is not npm lock version 2 or 3, when you do not have azlow.lockyet
The message looks like error[pm.git_dependency]. The name after pm. says which limit you hit. A package that is optional, or that does not support this operating system, is skipped and named in a skipped: line. A required package that does not support this machine stops the install.