I have seven active projects right now. At any given time, some are in active development, some need a monthly data update, and some just need occasional fixes.
The challenge isn't managing one project deeply—it's the context-switching cost of moving between them. Each switch has a start-up tax:
- What was I working on last time?
- Which terminals do I need open? Which environment needs to be activated?
- For maintenance tasks (e.g. updating seasonal data), what are the exact steps again?
These friction points compound. A five-minute task becomes twenty minutes of reorientation. I got tired of it, so I built systems to eliminate each one.
Problem 1: Environment Start-Up Cost
Every project needs a slightly different environment. Some have a Python venv to activate. Some start a local dev server. Some need a specific browser tab open. Setting all that up manually is tedious—and easy to forget a step.
My solution was a shell script,
launchProject.sh, bound to
Cmd+Shift+1. It opens a macOS folder picker, then
does everything needed to spin up the selected project:
# Open the project in VS Code
/usr/local/bin/code "$PROJECT_FOLDER"
# Open a terminal with git status + venv activated (if it's a Python project)
GIT_COMMAND="cd '$PROJECT_FOLDER' && git status"
if [[ "$FOLDER_NAME" == "NBA Moneyline" ]]; then
GIT_COMMAND+=" && source scrape/.venv/bin/activate"
fi
osascript -e "tell application \"Terminal\" to do script \"$GIT_COMMAND\""
# For Express projects: start the server and open localhost:3000
if [[ " ${EXPRESS_PROJECTS[@]} " =~ " ${FOLDER_NAME} " ]]; then
osascript -e "tell application \"Terminal\" to do script \"cd '$PROJECT_FOLDER' && npm run dev\""
sleep 2
open -a "Google Chrome" "http://localhost:3000"
fi One keystroke. VS Code opens to the project, a terminal opens with git status (so I immediately see what changed), the right venv activates, the dev server starts, and the browser opens to localhost. I go from zero to working in seconds.
The script handles each project's quirks: Python projects
get venv activated, Express projects get a server started,
Vite/React projects get localhost:5173 instead
of localhost:3000. Adding a new project means
adding its name to the right array.
Problem 2: Visual Noise in VS Code
VS Code's file explorer shows everything by default:
node_modules/, package-lock.json,
build output directories, screenshot folders. Most of that
is clutter you never need to see while coding.
Each project has a .vscode/settings.json that
hides everything irrelevant:
// .vscode/settings.json
{
"files.exclude": {
"node_modules": true,
"package-lock.json": true,
"Screenshots": true,
".venv": true
}
} The sidebar now only shows files I'd actually edit. This is a small thing, but it matters: when you switch into a project cold, a clean file tree helps you reorient faster.
I also use consistent top-level folder names across
projects—app/, public/,
scrape/, data/—so navigating a
project I haven't touched in a month still feels familiar.
The mental model transfers.
Problem 3: Reorientation for Repeated Processes
Some projects have multi-step maintenance workflows I run on a schedule. NBA Moneyline needs a full season's data scraped and migrated once a year. Trigram needs a new puzzle added each week, including a social post and a spreadsheet update. The Todoist NBA Schedule Saver gets a fresh scrape every preseason.
I don't do these often enough to have the steps memorized, but often enough that relearning them each time would be wasteful. My solution: a dedicated workflow doc at the project root.
Each doc is a numbered, step-by-step list of exactly what to do, written for my future self. No fluff—just commands and what to check. For example, the Trigram weekly workflow:
# Weekly Trigram Update Workflow
## 1. Select Next Trigram
Choose the next trigram from the spreadsheet (e.g. "TOU").
## 2. Run Automation Script
cd tools/automation
./add_new_trigram.sh TOU
This script:
- Adds the word dictionary to data/trigram-word-lists/
- Updates calendar.js with the new trigram
- Generates the Instagram announcement image
- Commits and pushes to main
## 3. Update Spreadsheet
Mark TOU as DONE.
## 4. Post to Instagram (Sunday ~midnight)
Use the generated PNG with caption:
"Trigram #[N] is now available! Play here: https://trigram.netlify.app" When I sit down to do the weekly Trigram update, I open this file and just follow the steps. No thinking required. The annual NBA Moneyline data migration works the same way—a single doc walks me through scraping, verification, and database migration.
These docs also serve as runbooks if I want to hand a project off or revisit it after a long break. Months from now, future-me will thank current-me for writing it down.
The Compound Effect
None of these systems is individually revolutionary. A shell script, a few lines of JSON, a markdown file. But they address different parts of the same root problem: the cost of switching contexts. Together, they get me from "I should work on Project X" to actually working on Project X in under a minute.
The other benefit: they lower the activation energy enough that I actually do maintenance tasks when they come up, rather than procrastinating because reorientation feels like too much work.
If you're juggling multiple projects, I'd start with the workflow docs. Writing down the exact steps for any repeated process—even if it only happens once a month—pays for itself the first time you use it.