Workspace Management: Multi-project VS Code Setup That Cut My Context Switching in Half

8 min read1521 words

Working on multiple related projects used to drain my mental energy. I'd constantly switch between VS Code windows, lose track of which terminal belonged to which project, and struggle with different configuration setups across codebases.

Then I discovered VS Code's workspace management features and everything changed. What used to take me 15 minutes of setup and mental context switching now happens in seconds.

Here's exactly how I've structured my multi-project workspace setup and the automation scripts that make it seamless.

The Problem with Multiple VS Code Windows

Before implementing proper workspace management, my development workflow looked like this:

  • 5+ VS Code windows open simultaneously
  • Different extensions enabled/disabled per project
  • Separate terminal windows for each project
  • Constantly Alt+Tab-ing between windows
  • Lost debugging configurations when switching contexts
  • Inconsistent settings across related projects

I was spending more time managing my development environment than actually developing.

Understanding VS Code Workspace Architecture

VS Code workspaces center around .code-workspace files - JSON configurations that define your multi-project environment. Here's the basic structure I use:

// project-suite.code-workspace
{
  "folders": [
    { "path": "./backend" },
    { "path": "./frontend" },
    { "path": "../shared/ui-components" }
  ],
  "settings": {
    "files.exclude": {
      "**/node_modules": true,
      "**/dist": true,
      "**/.next": true,
      "**/build": true
    }
  },
  "extensions": {
    "recommendations": [
      "ms-vscode.vscode-typescript-next",
      "esbenp.prettier-vscode",
      "dbaeumer.vscode-eslint"
    ]
  }
}

This configuration opens three project folders in a single VS Code window, each maintaining its own Git repository and project structure.

My Multi-Root Workspace Setup Process

Step 1: Organize Project Structure

I've found this folder organization works best for related projects:

client-project/
├── backend/              # API and server logic
├── frontend/             # Next.js or React app  
├── shared/               # Common utilities/components
├── docs/                 # Project documentation
├── scripts/              # Deployment and utility scripts
└── client-project.code-workspace

Each folder can be a separate Git repository or part of a monorepo, depending on the project needs.

Step 2: Configure Project-Specific Settings

Each project folder gets its own .vscode/settings.json for technology-specific configurations:

// backend/.vscode/settings.json
{
  "python.defaultInterpreterPath": "./venv/bin/python",
  "python.formatting.provider": "black",
  "python.linting.enabled": true,
  "python.linting.pylintEnabled": true,
  "files.exclude": {
    "**/__pycache__": true,
    "**/*.pyc": true,
    "**/venv": true
  },
  "editor.rulers": [88]
}
// frontend/.vscode/settings.json  
{
  "typescript.updateImportsOnFileMove.enabled": "always",
  "emmet.includeLanguages": {
    "typescriptreact": "html"
  },
  "tailwindCSS.experimental.classRegex": [
    "tw`([^`]*)",
    "tw=\"([^\"]*)"
  ],
  "css.validate": false
}

This hierarchy ensures that Python settings only apply to the backend folder, while TypeScript configurations stay isolated to the frontend.

Step 3: Set Up Unified Tasks and Debugging

The workspace file includes tasks that work across all projects:

"tasks": {
  "version": "2.0.0",
  "tasks": [
    {
      "label": "Build All",
      "dependsOrder": "sequence", 
      "dependsOn": ["Build Backend", "Build Frontend"]
    },
    {
      "label": "Build Backend",
      "type": "shell",
      "command": "npm run build",
      "options": {
        "cwd": "${workspaceFolder:backend}"
      },
      "group": "build",
      "problemMatcher": ["$tsc"]
    },
    {
      "label": "Build Frontend", 
      "type": "shell",
      "command": "npm run build",
      "options": {
        "cwd": "${workspaceFolder:frontend}"  
      },
      "group": "build",
      "problemMatcher": ["$tsc"]
    }
  ]
}

Now I can build all projects with Cmd+Shift+P → "Build All", and VS Code runs them in the correct sequence.

Debugging Configurations for Multi-Project Workspaces

Each project folder maintains its own debugging setup in .vscode/launch.json:

// backend/.vscode/launch.json
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Backend: FastAPI Dev",
      "type": "python", 
      "request": "launch",
      "program": "main.py",
      "console": "integratedTerminal",
      "env": {
        "PYTHONPATH": "${workspaceFolder}",
        "ENV": "development"
      }
    }
  ]
}
// frontend/.vscode/launch.json
{
  "version": "0.2.0", 
  "configurations": [
    {
      "name": "Frontend: Next.js Dev",
      "type": "node",
      "request": "launch", 
      "program": "${workspaceFolder}/node_modules/.bin/next",
      "args": ["dev"],
      "console": "integratedTerminal"
    },
    {
      "name": "Frontend: Chrome Debug",
      "type": "chrome",
      "request": "launch",
      "url": "http://localhost:3000", 
      "webRoot": "${workspaceFolder}"
    }
  ]
}

VS Code automatically prefixes debug configurations with the folder name, so I see "Backend: FastAPI Dev" and "Frontend: Next.js Dev" in the debug dropdown. No more confusion about which debugger belongs to which project.

Performance Optimization for Large Workspaces

With multiple projects in one workspace, VS Code can become sluggish without proper configuration. These settings keep everything running smoothly:

"settings": {
  "files.exclude": {
    "**/node_modules": true,
    "**/dist": true, 
    "**/.next": true,
    "**/build": true,
    "**/__pycache__": true,
    "**/venv": true
  },
  "search.exclude": {
    "**/node_modules": true,
    "**/dist": true
  },
  "files.watcherExclude": {
    "**/node_modules/**": true,
    "**/.git/objects/**": true,
    "**/.git/subtree-cache/**": true
  },
  "typescript.preferences.includePackageJsonAutoImports": "on"
}

I exclude build artifacts and dependencies from file watching, search, and the explorer. This prevents VS Code from indexing thousands of unnecessary files and keeps the interface responsive.

Automation Script for Quick Workspace Setup

Manual workspace creation gets tedious, so I built a script that generates the complete structure:

#!/bin/bash
# create-workspace.sh
 
PROJECT_NAME=$1
if [ -z "$PROJECT_NAME" ]; then
  echo "Usage: $0 <project-name>"
  exit 1
fi
 
echo "Setting up workspace: $PROJECT_NAME"
 
# Create project structure
mkdir -p "$PROJECT_NAME"
cd "$PROJECT_NAME" 
mkdir -p backend frontend shared docs scripts
 
# Generate workspace configuration
cat > "$PROJECT_NAME.code-workspace" <<EOF
{
  "folders": [
    { "path": "./backend" },
    { "path": "./frontend" }, 
    { "path": "./shared" },
    { "path": "./docs" }
  ],
  "settings": {
    "files.exclude": {
      "**/node_modules": true,
      "**/dist": true,
      "**/.next": true, 
      "**/build": true,
      "**/__pycache__": true
    },
    "editor.formatOnSave": true,
    "editor.codeActionsOnSave": {
      "source.fixAll.eslint": true
    }
  },
  "extensions": {
    "recommendations": [
      "ms-vscode.vscode-typescript-next",
      "esbenp.prettier-vscode", 
      "dbaeumer.vscode-eslint",
      "ms-python.python",
      "bradlc.vscode-tailwindcss"
    ]
  }
}
EOF
 
# Create project-specific .vscode directories
mkdir -p backend/.vscode frontend/.vscode
 
# Backend settings
cat > backend/.vscode/settings.json <<EOF
{
  "python.defaultInterpreterPath": "./venv/bin/python",
  "python.formatting.provider": "black",
  "python.linting.enabled": true
}
EOF
 
# Frontend settings  
cat > frontend/.vscode/settings.json <<EOF
{
  "typescript.updateImportsOnFileMove.enabled": "always",
  "emmet.includeLanguages": {
    "typescriptreact": "html"
  }
}
EOF
 
# Initialize Git repositories
cd backend && git init && cd ..
cd frontend && git init && cd ..
 
echo "Workspace created successfully!"
echo "Open with: code $PROJECT_NAME.code-workspace"

Now creating a new multi-project workspace takes one command:

./create-workspace.sh client-dashboard
code client-dashboard/client-dashboard.code-workspace

Extension Management Across Projects

Different projects need different extensions, but I want consistency across team members. Here's how I handle extension recommendations:

"extensions": {
  "recommendations": [
    // Core extensions for all projects
    "ms-vscode.vscode-typescript-next",
    "esbenp.prettier-vscode",
    "dbaeumer.vscode-eslint",
    
    // Technology-specific extensions
    "ms-python.python",
    "bradlc.vscode-tailwindcss",
    "ms-vscode.vscode-json",
    
    // Productivity extensions  
    "alefragnani.project-manager",
    "johnpapa.vscode-peacock"
  ]
}

When team members open the workspace, VS Code prompts them to install recommended extensions. This ensures everyone has the same tooling without forcing global installations.

I use the Peacock extension to color-code different workspace windows - blue for client work, green for personal projects, red for urgent fixes. This visual distinction eliminates the mental overhead of tracking which window contains which project.

Git Integration with Multi-Root Workspaces

Each project folder can maintain its own Git repository. VS Code's source control panel shows all repositories with folder prefixes:

  • Backend (main) - 3 changes
  • Frontend (feature/auth) - 7 changes
  • Shared (main) - 0 changes

I can stage, commit, and push changes to each repository independently, or use the integrated terminal to run Git commands with proper working directory context.

For monorepos, the entire workspace shares one Git repository, which simplifies dependency management but requires more careful branch strategies.

Team Collaboration and Workspace Sharing

The workspace configuration files live in version control alongside the projects. Team members clone the repositories and immediately have:

  • Identical folder structure and settings
  • Same extension recommendations
  • Shared task and debugging configurations
  • Consistent code formatting and linting rules

New developers join the project and run:

git clone git@github.com:company/project-suite.git
cd project-suite
code project-suite.code-workspace  

VS Code handles the rest - installing recommended extensions, applying settings, and configuring the development environment.

Common Workspace Management Issues

Settings Conflicts

Some VS Code settings can't be applied at the folder level and will appear grayed out. These include UI preferences like theme, sidebar position, and window management options. Keep these settings at the user level to avoid conflicts.

Performance with Large Codebases

Adding too many folders or failing to exclude build artifacts will slow down VS Code. I regularly review the file exclusion patterns and remove unused folders from active workspaces.

Extension Loading Problems

Extensions that modify global VS Code behavior (like vim keybindings) can conflict with project-specific extensions. I keep global behavior extensions in user settings and project-specific tools in workspace recommendations.

Debug Configuration Confusion

In multi-root workspaces, debug configurations display with folder prefixes. If you don't see your launch configuration, check that it exists in the correct project folder's .vscode/launch.json file.

The Results

This workspace management approach transformed my development workflow:

  • Context switching time dropped from ~15 minutes to under 30 seconds
  • No more hunting for the right terminal or losing track of running processes
  • Team onboarding went from half a day of environment setup to 10 minutes
  • Debugging across services became seamless with unified configurations
  • Code formatting and linting stay consistent across all related projects

The initial setup takes about an hour per project suite, but the productivity gains compound daily. I now manage 8 different client workspaces and 3 personal project suites without the mental overhead that used to exhaust me.

Multi-root workspaces aren't just a VS Code feature - they're a complete paradigm shift for how you think about project organization and development workflow. Once you experience the unified environment, managing projects in separate windows feels primitive.

Start with one related set of projects, create the .code-workspace file, and experience the difference. Your future self will thank you for making the switch.