Picture this: you're starting your development day, coffee in hand, ready to build. But before you can write a single line of code, you need to:
- Open Terminal #1 →
cd backend→npm run dev - Open Terminal #2 →
cd frontend→pnpm run dev - Open Terminal #3 →
cd mobile-app→bunx expo run:android - Switch between terminals to check if they're running
- Forget which terminal is which
Sound familiar? If you work with monorepos or multi-service applications, you've been there. I was losing two to three minutes every single morning on this repetitive task. Today I'm sharing how I automated the entire process with a simple PowerShell script and a package.json integration that saves me time and mental energy every day.
The problem: terminal chaos in monorepos
Why this matters
Modern full-stack development often involves multiple services running simultaneously:
- Backend API — Node.js/Express, NestJS, and friends
- Frontend application — Next.js, React, Vue
- Mobile app — React Native, Expo
- Sometimes more: microservices, worker processes, background jobs
Each service requires its own terminal, its own working directory, a specific startup command, and a manual check that it's actually running.
The real cost
Beyond the obvious time waste, the hidden costs are worse:
- Context switching — jumping between terminals breaks your flow.
- Mental overhead — remembering which terminal does what.
- Error-prone — easy to run the wrong command or forget a service.
- Scalability — it gets exponentially worse with every service you add.
My specific use case
In my courier management system monorepo I needed to run three things:
- Backend API — Node.js with Prisma ORM
- SaaS dashboard — Next.js with pnpm
- Mobile app — React Native with Expo
Three different package managers, three different commands, three different directories.
The solution: PowerShell + Windows Terminal integration
I wrote a PowerShell script that leans on Windows Terminal's tabbed interface to launch every server in organised, colour-coded tabs from a single command.
Key features
- One command launch —
npm run startbrings everything up. - Colour-coded tabs — each service gets its own colour for instant identification.
- Selective startup — skip specific services with flags.
- IDE integration — clickable straight from the VS Code / WebStorm npm scripts panel.
- Zero configuration — works out of the box once set up.
Step-by-step implementation
Step 1 — create the PowerShell script
Create a file called start-servers.ps1 in your monorepo root:
param(
[switch]$SkipApp,
[switch]$SkipBackend,
[switch]$SkipSaas,
[switch]$Help
)
if ($Help) {
Write-Host "Multi-Server Launcher" -ForegroundColor Green
Write-Host "Usage:" -ForegroundColor Yellow
Write-Host " .\start-servers.ps1 # Start all servers"
Write-Host " .\start-servers.ps1 -SkipApp # Skip mobile app"
Write-Host " .\start-servers.ps1 -SkipBackend # Skip backend"
Write-Host " .\start-servers.ps1 -SkipSaas # Skip SaaS/frontend"
exit
}
$rootPath = Get-Location
$cmd = "wt --size 170,50"
# Backend
if (-not $SkipBackend) {
$backendPath = Join-Path $rootPath "backend_folder"
if (Test-Path $backendPath) {
$cmd += " --title ""Backend API"" --tabColor ""#68D391"" -d .\backend_folder pwsh -NoExit -Command ""npm run dev"""
}
}
# Frontend / SaaS
if (-not $SkipSaas) {
$frontendPath = Join-Path $rootPath "frontend_folder"
if (Test-Path $frontendPath) {
if ($cmd -ne "wt --size 170,50") { $cmd += " ``;" }
$cmd += " sp --horizontal --title ""SaaS Dashboard"" --tabColor ""#9F7AEA"" -d .\frontend_folder pwsh -NoExit -Command ""pnpm dev"""
}
}
# Mobile app
if (-not $SkipApp) {
$appPath = Join-Path $rootPath "app_folder"
if (Test-Path $appPath) {
if ($cmd -ne "wt --size 170,50") { $cmd += " ``;" }
$cmd += " sp --horizontal --title ""Mobile App"" --tabColor ""#61DAFB"" -d .\app_folder pwsh -NoExit -Command ""bunx expo run:android"""
}
}
if ($cmd -eq "wt --size 170,50") {
Write-Host "No servers selected to start!" -ForegroundColor Red
exit 1
}
Write-Host "Starting servers..." -ForegroundColor Green
Invoke-Expression $cmdStep 2 — add npm scripts to package.json
Add these scripts to your root package.json:
{
"scripts": {
"start": "powershell -ExecutionPolicy Bypass -File ./start-servers.ps1",
"start:server-saas": "powershell -ExecutionPolicy Bypass -File ./start-servers.ps1 -SkipApp",
"start:backend": "powershell -ExecutionPolicy Bypass -File ./start-servers.ps1 -SkipApp -SkipSaas",
"start:frontend": "powershell -ExecutionPolicy Bypass -File ./start-servers.ps1 -SkipApp -SkipBackend",
"start:app": "powershell -ExecutionPolicy Bypass -File ./start-servers.ps1 -SkipBackend -SkipSaas"
}
}Step 3 — customise for your project
- Update folder names — replace
backend_folder,frontend_folderandapp_folderwith your real directories. - Update commands — swap
npm run dev,pnpm devandbunx expo run:androidfor your actual startup commands. - Update colours — change the hex values (
#68D391,#9F7AEA,#61DAFB) to taste. - Update titles — rename the tab titles to match your services.
Understanding the code
Windows Terminal command structure
wt --size 170,50 starts Windows Terminal with a specific window size. wt is Windows Terminal's own CLI.
Adding tabs
--title "Backend API" --tabColor "#68D391" -d .\backend_folder pwsh -NoExit -Command "npm run dev"--title— the tab title shown in the terminal.--tabColor— hex colour for the tab, which is what makes the tabs scannable at a glance.-d— the working directory for that tab.pwsh -NoExit— PowerShell that stays open after the command finishes.-Command— the actual command to run.
Splitting panes
The escaped semicolon separates wt commands, and sp --horizontal creates a horizontal split pane — so multiple tabs share one window instead of stacking up as separate windows.
Conditional logic
if (-not $SkipBackend) { … } is the PowerShell idiom for “the flag was not passed”. When it wasn't, the backend tab is added to the startup sequence.
Benefits and impact
Time savings
- Before — two to three minutes every morning starting servers by hand.
- After — one click or command, five to ten seconds.
- Annual saving — roughly ten to fifteen hours a year if you start dev work daily.
Mental clarity
- Organised — colour-coded tabs make it obvious which service is which.
- Consistent — the same setup every time, so there are no mistakes to make.
- Lower cognitive load — one less thing to hold in your head.
Team productivity
Share the setup with your team and everyone gets:
- New developers contributing sooner.
- A consistent development environment.
- Fewer “it works on my machine” conversations.
Advanced tips and variations
1. Different package managers
npm run dev # npm
pnpm dev # pnpm
yarn dev # yarn
bun run dev # bun2. Custom environment variables
$cmd += " pwsh -NoExit -Command ""$env:NODE_ENV='development'; npm run dev"""3. Error handling
try {
Invoke-Expression $cmd
Write-Host "All servers started successfully!" -ForegroundColor Green
} catch {
Write-Host "Error: $($_.Exception.Message)" -ForegroundColor Red
}4. Health checks
After starting, verify the servers actually came up:
Start-Sleep -Seconds 5
Invoke-WebRequest -Uri "http://localhost:3000" -UseBasicParsing5. macOS / Linux alternative
The same idea ports to Unix with gnome-terminal or osascript:
#!/bin/bash
gnome-terminal --tab --title="Backend" -- bash -c "cd backend && npm run dev; exec bash"Common issues and solutions
“wt command not found”
Install Windows Terminal from the Microsoft Store, or make sure it's on your PATH.
Execution policy error
The -ExecutionPolicy Bypass flag in the npm script handles it. If it persists:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUserScript runs but servers don't start
- Check the folder paths are correct.
- Check the commands work when run manually.
- Check the package managers are installed (npm, pnpm, bun).
Tabs close immediately
Make sure -NoExit is in the pwsh command so the tab stays open.
Real-world use cases
- Full-stack development — API and web app running side by side.
- Microservices — launch several services at once for local integration testing.
- Mobile plus backend — a mobile app and the API it talks to.
- Team onboarding — new hires start contributing on day one.
Conclusion: automate the boring stuff
This small automation has become one of my most valuable developer tools. It isn't really about saving a few minutes — it's about removing friction from your daily workflow, eliminating decision fatigue, creating consistency, and spending your energy on building rather than on setup.
Key takeaways
- Automation compounds — small savings add up over months and years.
- Simple solutions win — this is about a hundred lines of code with an outsized impact.
- The tools exist — Windows Terminal has powerful CLI features; use them.
- Share knowledge — if it helps you, it will help your team.
What repetitive tasks have you automated? I'd genuinely like to hear the workflows other developers have sanded down — that's usually where the best ideas come from.