Starwards Monorepo Workflow
Overview
Starwards uses npm workspaces with 4 interdependent modules. Understanding build order, dependencies, and workflow prevents wasted time.
Core principle: Core builds first. Others depend on it.
Monorepo Structure
starwards/ ├── package.json # Root workspace config ├── modules/ │ ├── core/ # Game logic, shared types │ │ ├── src/ # TypeScript source │ │ ├── cjs/ # Built CommonJS (gitignored) │ │ └── package.json # @starwards/core │ ├── server/ # Colyseus rooms, game server │ │ ├── src/ │ │ ├── cjs/ # Built server code │ │ └── package.json # @starwards/server │ ├── browser/ # React UI, PixiJS rendering │ │ ├── src/ │ │ ├── dist/ # Webpack bundle │ │ └── package.json # @starwards/browser │ ├── node-red/ # Node-RED integration │ │ ├── src/ │ │ ├── dist/ │ │ └── package.json # @starwards/node-red │ └── e2e/ # Playwright tests │ └── test/ └── node_modules/ # Shared dependencies (hoisted)
Module Dependencies
core (no deps) ├─→ server (depends on core) ├─→ browser (depends on core) ├─→ node-red (depends on core) └─→ e2e (depends on all)
Critical: Core must build before others.
Build Commands
From Root Directory
Build all modules (correct order)
npm run build
Runs: core → (server, browser, node-red in parallel)
Build specific module
npm run build:core npm run build:browser npm run build:server npm run build:node-red
Clean all build artifacts
npm run clean
Removes: cjs/, dist/ from all modules
Fresh build
npm run clean && npm run build
From Module Directory
Build just this module
cd modules/core && npm run build cd modules/browser && npm run build
Watch mode (rebuild on file change)
cd modules/core && npm run build:watch
When to use:
-
Root commands: CI/CD, fresh builds, building everything
-
Module commands: Active development of that module
Development Workflow (3 Terminals)
Terminal 1: Core Watch Mode
cd modules/core && npm run build:watch
Purpose: Automatically rebuild core when files change
When running: Any time you're editing core/ files
Status: Keep running in background
Troubleshooting:
-
Not rebuilding? Check console for errors
-
Server not seeing changes? Core build may have failed
Terminal 2: Webpack Dev Server
cd modules/browser && npm start
Purpose: Hot-reload browser UI
Serves: http://localhost:3000
When running: When developing browser/ UI
Troubleshooting:
-
Port 3000 taken? lsof -ti:3000 | xargs kill -9
-
Webpack overlay shows [object Object]? Check browser console (F12)
-
Changes not appearing? Check if core watch is running
Terminal 3: API Server
node -r ts-node/register/transpile-only modules/server/src/dev.ts
Purpose: Run game server with Colyseus
Serves: http://localhost:8080
When running: Always (browser needs API)
Troubleshooting:
-
Server crashes? Check if core is built
-
Changes not appearing? Restart this terminal (server doesn't auto-reload)
Workflow Summary
-
Start Terminal 1 (core watch)
-
Start Terminal 2 (webpack dev server)
-
Start Terminal 3 (API server)
-
Edit code
-
Browser auto-reloads (Terminal 2 hot-reload)
-
Core changes → rebuild (Terminal 1 watches)
-
Server changes → manually restart Terminal 3
Testing in Monorepo
All Tests
From root: Run all module tests
npm test
Runs: core tests, server tests, node-red tests
Specific module
npm test -- --projects=core npm test -- --projects=server npm test -- --projects=node-red
Specific file
npm test -- modules/core/test/shield.spec.ts
E2E Tests
E2E tests require ALL modules built
npm run build # Build everything first npm run test:e2e # Then run E2E
Update snapshots
npm run test:e2e -- --update-snapshots
Why build first: E2E tests start real server, which needs built modules.
Watch Mode During Development
Watch all tests
npm test -- --watch
Watch specific module
cd modules/core && npm test -- --watch
Tip: Run in 4th terminal while developing.
Common Workflows
Adding New Core Feature
1. Ensure core watch running
cd modules/core && npm run build:watch # Terminal 1
2. Write test (TDD)
modules/core/test/shield.spec.ts
3. Run test (should fail RED)
npm test -- modules/core/test/shield.spec.ts
4. Implement feature
modules/core/src/ship/shield.ts
(watch rebuilds automatically)
5. Test passes GREEN
npm test -- modules/core/test/shield.spec.ts
6. Verify dependents still work
npm test # All tests npm run test:e2e # E2E tests
Adding New UI Widget
1. Ensure everything running
Terminal 1: core watch
Terminal 2: webpack dev server
Terminal 3: API server
2. Write E2E test (TDD)
modules/e2e/test/shield-widget.spec.ts
npm run test:e2e -- shield-widget.spec.ts # Fails RED
3. Create widget
modules/browser/src/widgets/shield.ts
(webpack hot-reloads automatically)
4. Test passes GREEN
npm run test:e2e -- shield-widget.spec.ts
5. Verify
npm run test:e2e # All E2E
Adding New Server Feature
1. Core watch running (Terminal 1)
2. Write test
modules/server/test/shield-command.spec.ts
npm test -- modules/server/test/shield-command.spec.ts # RED
3. Implement
modules/server/src/ship/room.ts
npm run build:server
4. Restart server (Terminal 3)
Ctrl+C, then re-run command
5. Test passes GREEN
npm test -- modules/server/test/shield-command.spec.ts
6. Verify E2E
npm run test:e2e
Build Order & Dependencies
Automatic (from root):
npm run build
1. Build core first (required)
2. Build server, browser, node-red in parallel
Manual (module by module):
CORRECT order
npm run build:core # 1st npm run build:server # 2nd (can run parallel with browser) npm run build:browser # 2nd (can run parallel with server) npm run build:node-red # 2nd (can run parallel with others)
WRONG order
npm run build:browser # FAILS - core not built yet npm run build:core # Too late
Path Aliases
All modules can import core using @starwards/core :
// In server, browser, or node-red: import { ShipState } from '@starwards/core';
Configured in:
-
tsconfig.json (TypeScript)
-
jest.config.js (Jest tests)
-
webpack.common.js (Browser webpack)
Maps to:
-
Development: modules/core/src
-
Production: modules/core/cjs
Common Pitfalls
Pitfall 1: Core Not Built
Symptom:
Error: Cannot find module '@starwards/core'
Solution:
npm run build:core
Or start watch mode: cd modules/core && npm run build:watch
Pitfall 2: Server Not Restarted
Symptom: Server code changes not appearing
Solution: Server doesn't auto-reload. Restart Terminal 3:
Ctrl+C node -r ts-node/register/transpile-only modules/server/src/dev.ts
Pitfall 3: Webpack Not Running
Symptom: Browser changes not appearing
Solution: Start Terminal 2:
cd modules/browser && npm start
Pitfall 4: Build Artifacts Stale
Symptom: Weird errors, imports failing, tests failing randomly
Solution: Fresh build:
npm run clean npm ci # Fresh dependencies npm run build
Pitfall 5: Wrong Directory for npm test
Symptom: Tests not found
Solution: Run from root, not module:
CORRECT
npm test
WRONG
cd modules/core && npm test # Works but limits to core only
Pitfall 6: E2E Without Build
Symptom: E2E tests fail, server doesn't start
Solution:
npm run build # Build all first npm run test:e2e # Then E2E
Pitfall 7: Dependency Version Mismatch
Symptom: "Multiple versions of package X"
Solution:
npm ci # Use exact versions from package-lock.json npm dedupe # Deduplicate dependencies
CI/CD Monorepo Considerations
GitHub Actions workflow:
- run: npm ci # Install all workspaces
- run: npm run test:types # Type check all modules
- run: npm run test:format # Format check all modules
- run: npm run build # Build all modules (correct order)
- run: npm test # Test all modules
- run: npm run test:e2e # E2E tests (after build)
Order matters: Build must complete before E2E.
Debugging Monorepo Issues
Check Build Status
Verify all modules built
ls modules/core/cjs # Should exist ls modules/browser/dist # Should exist ls modules/server/cjs # Should exist
Check Dependencies
List workspace dependencies
npm ls @starwards/core # Who depends on core?
Check if hoisted correctly
ls node_modules/@starwards # Should see symlinks
Fresh Start
Nuclear option - full reset
npm run clean # Remove build artifacts rm -rf node_modules # Remove dependencies rm package-lock.json # Remove lockfile npm install # Fresh install npm run build # Fresh build
Use when: Everything is broken, nothing makes sense.
Integration with Other Skills
-
starwards-tdd - Test patterns for each module type
-
starwards-verification - Commands verify all modules
-
starwards-debugging - Debug issues across module boundaries
Quick Reference
Action Command
Build all npm run build
Build core only npm run build:core
Core watch cd modules/core && npm run build:watch
Test all npm test
Test core only npm test -- --projects=core
Clean all npm run clean
Fresh build npm run clean && npm ci && npm run build
Dev workflow 3 terminals: core watch, webpack, server
The Bottom Line
Remember:
-
Core builds first, always
-
Watch mode saves time (Terminal 1)
-
Server needs manual restart (Terminal 3)
-
Browser hot-reloads (Terminal 2)
-
Run tests from root
-
Build before E2E
-
When in doubt: fresh build