| name | nx-workspace-expert |
| description | Deep Nx monorepo expertise including CNW workspace creation, executors, Docker plugin, migrations, and process spawning. Use for Nx workspace issues, creating workspaces, understanding executor behavior, debugging Nx-specific problems, or Docker builds. Triggers on "Nx", "workspace", "CNW", "create-nx-workspace", "executor", "nx migrate", "nx docker". |
Nx Workspace Expert
Acronyms
- CNW: Create Nx Workspace (
packages/create-nx-workspace/)
- CNP: Create Nx Plugin (
packages/create-nx-plugin/)
- NXC: Nx CLI team issues (Linear)
- DOC: Documentation team issues
- CLOUD: Nx Cloud team issues
Create Nx Workspace (CNW)
Basic Usage
npx create-nx-workspace@latest
npx -y create-nx-workspace@latest myworkspace --preset=react-monorepo --no-interactive
npx -y create-nx-workspace@latest
Common Presets
| Preset | Description |
|---|
react-monorepo | React apps + shared libs |
angular-monorepo | Angular apps + shared libs |
node-monorepo | Node.js apps (Express, Nest) |
vue-monorepo | Vue apps + shared libs |
react-standalone | Single React app |
next | Next.js app |
nest | NestJS app |
ts | TypeScript library |
Useful Options
--packageManager=pnpm
--no-interactive
--appName=api
--framework=nest
--e2eTestRunner=playwright
--unitTestRunner=vitest
--nxCloud=skip
--docker
Testing/Debugging Pattern
cd /tmp
npx -y create-nx-workspace@latest testworkspace \
--preset=node-monorepo \
--appName=api \
--framework=nest \
--no-interactive \
--nx-cloud=skip
Executor Code Paths
run-commands Spawning Logic
Location: packages/nx/src/executors/run-commands/run-commands.impl.ts:130-163
| Condition | Code Path | Spawning Method |
|---|
| Single command + PTY supported | runSingleCommandWithPseudoTerminal() | PTY (Rust native) |
| Parallel commands | ParallelRunningTasks | Node exec() with piped stdio |
| Serial commands | SeriallyRunningTasks | PTY if supported |
PTY Check Conditions (lines 130-138)
const isSingleCommandAndCanUsePseudoTerminal =
isSingleCommand &&
usePseudoTerminal &&
process.env.NX_NATIVE_COMMAND_RUNNER !== 'false' &&
!normalized.commands[0].prefix &&
normalized.usePty;
Key Files
run-commands.impl.ts - Entry point with routing logic
running-tasks.ts - Task runner implementations
pseudo-terminal.ts - PTY wrapper for Rust bindings
packages/nx/src/native/ - Rust native bindings
Debugging Code Paths
Don't assume - verify with logging in node_modules:
console.log('CODE PATH:', 'runSingleCommandWithPseudoTerminal');
Nx Docker Plugin (@nx/docker)
Target Naming
Use docker:build NOT docker-build
Dockerfile Requirements
- MUST be named exactly
Dockerfile (not *.dockerfile)
- Located in project root directory
Minimal Configuration
{
"docker:build": {
"options": {
"cwd": "",
"file": "apps/myapp/Dockerfile"
}
}
}
- No executor needed (inferred by plugin)
nx-release-publish target is auto-inferred
Sub-Projects for Multiple Images
apps/myapp/
├── project.json
├── Dockerfile
└── executor/
├── project.json # Separate project
└── Dockerfile
Migration Testing
NEVER Use Tags
npx nx migrate @next
npx nx migrate 22.0.0-beta.7
Complete Migration Process
npx nx migrate 22.0.0
pnpm install
npx nx migrate --run-migrations
cat package.json | grep '"nx"'
Why Tags Are Dangerous
@next points to next major (v23), not current beta (v22)
- Always verify:
npm view nx@next version
Common Issues & Fixes
Stuck Processes
lsof -i :PORT | grep LISTEN
kill PID
After Modifying package.json
ALWAYS run nx sync - updates inferred targets
1. Modify package.json
2. nx sync
3. git add && git commit
File Reversions
Usually linting/formatting. Verify with git diff.
TSC Errors in Isolation
Normal - use project-level checks: nx run PROJECT:typecheck
Testing Conventions
File Extensions
Use .spec.ts NOT .test.ts
Vitest Config
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
globals: true,
environment: 'node',
include: ['src/**/*.{test,spec}.{js,ts,jsx,tsx}'],
}
});
Nx Vite Plugin
Add project to nx.json Vite plugin includes for inferred targets.
GitHub Actions Notes
setup-node Side Effects
setup-node with registry-url sets NODE_AUTH_TOKEN (even dummy placeholder).
When migrating away (e.g., to mise), this side effect is lost.
NPM Trusted Publisher (OIDC)
- Uses
id-token: write permission
- No token secrets needed
- CI detection should use
GITHUB_ACTIONS env var
Key Package Locations
| Package | Location |
|---|
| CNW | packages/create-nx-workspace/ |
| CNP | packages/create-nx-plugin/ |
| Core Nx | packages/nx/ |
| run-commands | packages/nx/src/executors/run-commands/ |
| PTY bindings | packages/nx/src/native/ |
Investigation Best Practices
- Verify code path FIRST - don't assume
- Add logging to node_modules to confirm execution
- Check for feature flags/env vars that change behavior
- Watch for multiple implementations:
- Single vs parallel commands
- PTY vs spawn vs exec
- Native (Rust) vs JavaScript