npm + git orchestration

Stop manually releasing
interdependent packages.

xnpm discovers your packages, maps who depends on what, and runs install → build → test → publish → push in the right order — across one package or fifty.

One global install. Run from any folder. Works with single packages, monorepos, and independent repos side by side.

terminal
$ xnpm --build --test --publish --push
↳ @x12i/core 1.4.2 → 1.5.0 published
↳ @x12i/utils 2.1.0 → 2.2.0 published
↳ @x12i/api 0.7.4 → 0.8.0 published
git push → done

not installed yet?  ↓ install xnpm


Why xnpm

Multi-package releases are
painful to do by hand.

When packages depend on each other, the order matters, the steps multiply, and one mistake means a broken release. xnpm makes it automatic and safe.

The problem

You have packages that depend on each other

When @scope/api depends on @scope/core, you have to publish core first, update api to consume the new version, then publish api. Across 5 packages, this is a 20-step process you run from memory.

The solution

xnpm figures out the order and does it

It reads every package.json, maps who depends on what, and runs the full lifecycle in dependency-first order — automatically updating each package to consume freshly published siblings before they're published themselves.

The risk

Publishing the wrong files is invisible until it's too late

A misplaced .npmrc or .env file in your published package silently leaks credentials. By the time anyone notices, it's already on npm. xnpm blocks this before every publish.

The boundary

It doesn't replace npm or git — it runs them

xnpm calls the native npm and git commands on your machine. No new package manager, no custom dependency resolution, no reinvented wheel. Your existing .npmrc, auth, and git config all apply.


How it works

Discover, order, execute.

Run xnpm from any folder. It finds your packages, sorts them, then runs exactly the steps you asked for — nothing more.

01
discover
Find all package.json files recursively
02
graph
Map local deps, sort dependency-first
03
install
npm install in correct order
04
build
npm run build if script exists
05
test
npm test if real script exists
06
publish
pack check → version bump → publish
07
push
git add / commit / push

Steps 1–3 always run. Steps 4–7 only run when the corresponding flag is passed.


Features

Safe by default.
Flexible when you need it.

Every decision was made to avoid the class of mistakes that happen when you manage multi-package releases manually.

GRAPH

Dependency-aware ordering

Reads every package's dependencies, finds local relationships, and runs packages in dependency-first order. Cycles are detected and reported before any commands run.

REPOS

Monorepo & multi-repo

Detects whether packages share a git root. In a monorepo, git push runs once at the end. In a multi-repo layout, each repo pushes after its own lifecycle completes.

SAFE

Publish safety by default

Validates .gitignore and .npmignore, creates one if missing. Runs npm pack --dry-run twice — before and after the version bump. If any .env or .npmrc would be included, publishing is blocked.

FILTER

Package selection

Target specific packages with --package by exact name, or --filter with glob patterns like @x12i/* or @x12i/ai-*. Multiple filters are OR-based.

INIT

First publish & git setup

--new-public and --new-private handle first-time npm publication without a version bump. --create-git initializes local repos and optionally creates remotes on GitHub, GitLab, or Bitbucket.

NPMRC

Root .npmrc resolution

Uses each package's own .npmrc if present, falls back to the invocation root via NPM_CONFIG_USERCONFIG. Never copies or prints your auth token. Tokens are redacted from all output.

CLEAN

Override cleanup

--clean-local removes only file: overrides for packages in the current run. --clean-all removes the entire overrides object. A second npm install runs automatically so the lockfile stays in sync.

RPRT

Report mode

Without --report, native output streams directly. With it, a concise summary shows package counts, version changes, git results, security checks, and failure details. Works with --dry-run too.

ASK

Plain English, zero AI

Describe workflows in plain English. xnpm ask resolves them deterministically — a shipped phrase catalog, not an LLM. Unknown requests fail with examples, not guesses. Dangerous ops require your confirmation.


Natural language

Say what you want.
xnpm figures out the flags.

xnpm ask turns plain English into the same validated xnpm command you would type by hand — deterministic catalog matching, not AI. Safe ops run immediately; publish, push, and git operations wait for your confirmation.

xnpm ask
$ xnpm ask "publish all @x12i packages and push"
I understood this as:
xnpm --filter "@x12i/*" --build --test --publish --push --report
This will:
- Select packages matching @x12i/*
- Run install, build, and test
- Publish in dependency-aware order
- Push git changes ⚠ irreversible
Execute? [y/N]y
↳ @x12i/core 1.4.2 → 1.5.0 published
↳ @x12i/api 0.7.4 → 0.8.0 published
git push → done
The friction

Flags are precise. Intent is not.

You know what you want — "install and test everything under @x12i." Translating that into --filter "@x12i/*" --build --test every time is overhead. It's worse when you hand off release steps to someone else.

The guarantee

Same engine. Clearer entry point.

xnpm ask is not a separate tool. It resolves to normal xnpm flags, uses the same validator and execution plan, and never runs commands it didn't explicitly map from the catalog. Unknown input fails with examples — not guesses.

The safety

Understand before you execute.

Publish, push, connect, and git creation ops are irreversible in practice. xnpm ask shows exactly what it will run and asks for y/N before any dangerous step — especially when the input came from natural language.

You might sayResolves to
Install & lifecycle
install all packagesxnpm
build and test everythingxnpm --build --test
install, build and test all @x12i packagesxnpm --filter "@x12i/*" --build --test
publish all @x12i packages and pushxnpm --filter "@x12i/*" --build --test --publish --push --report
create new private npm packages for @x12ixnpm --filter "@x12i/*" --build --test --new-private --report
Git connect & setup
connect git repo to git@github.com:x12i/packages.gitxnpm --connect "git@github.com:x12i/packages.git"
connect monorepo to git@github.com:x12i/packages.gitxnpm --connect "..." --repo-mode monorepo
link remote git@github.com:x12i/core.git and pushxnpm --connect "..." --push --report
create git and connect to git@github.com:x12i/demo.gitxnpm --create-git --connect "..."
create private github repo for x12i and pushxnpm --create-git --git-create-remote --git-provider github ...

Connect and git-create-remote operations require y/yes confirmation before running.


Commands

Compose what you need.

Flags are additive. xnpm, xnpm i, and xnpm install are equivalent. The alias x12i-npm also works.

FlagWhat it does
Lifecycle
--buildRun npm run build after install
--testRun npm test after build
--publishBump minor version and publish to npm
--pushCommit and push via git after lifecycle completes
--reportSuppress noisy output, show high-level summary only
--dry-runShow planned execution order and steps without modifying any files
--no-version-bumpPublish the current version as-is, skip the minor bump
--clean-localRemove local file: overrides from package.json
--clean-allRemove the entire overrides object from package.json
Selection
--package <name>Select a specific package by exact name (repeatable)
--filter <glob>Select packages matching a glob, e.g. @x12i/* or @x12i/ai-*
Creation (opt-in)
--new-publicFirst-publish as a public npm package — no version bump
--new-privateFirst-publish as a restricted npm package — scoped names only
--create-gitInitialize local git repo where missing, run initial commit
--repo-mode <mode>monorepo or multi-repo — required when creating git across multiple packages
--git-create-remoteCreate a new remote repo via provider API (GitHub, GitLab, Bitbucket)
--connect <url>alias: --git-link Attach local repo to an existing remote — clearer name for --git-link, same behavior
Install only
xnpm
Install and build
xnpm --build
Install, build, test
xnpm --build --test
Full release
xnpm --build --test --publish --push
Full release, summary only
xnpm --build --test --publish --push --report
Dry run — preview without executing
xnpm --build --test --publish --push --dry-run
Publish without version bump
xnpm --publish --no-version-bump
Target a scope
xnpm --filter "@x12i/*" --build --publish
First publish as private
xnpm --build --test --new-private --push --report
Connect to remote (monorepo)
xnpm --connect git@github.com:x12i/pkg.git --repo-mode monorepo --push
Natural language
xnpm ask "build and test all @x12i packages"
One-off via npx
npx @x12i/npm --build --test

Install

Install once, run everywhere.

Global install makes xnpm available from any folder on your machine. The same command with @latest keeps it up to date.

To update: run the same command — @latest always installs the newest version
Requires Node.js ≥ 20  ·  npmjs.com/package/@x12i/npm ↗