Ides Editors

Settings Sync Across Machines

A practical guide to VS Code Settings Sync for keeping extensions, keybindings, snippets, and preferences consistent across multiple development machines.

Settings Sync Across Machines

Every developer who works on more than one machine has felt the pain of setting up VS Code from scratch. You install extensions one by one, adjust settings, recreate snippets, customize keybindings — and a week later you realize the configuration on your laptop has drifted from your desktop. Settings Sync solves this by synchronizing your entire VS Code configuration through your GitHub or Microsoft account.

I use three machines daily: a desktop workstation, a laptop, and a cloud development server. Before Settings Sync, I maintained a dotfiles repository with manual sync scripts. Now everything stays in sync automatically. This guide covers the built-in Settings Sync feature, what it synchronizes, how to handle machine-specific settings, and strategies for teams.

Prerequisites

  • VS Code v1.48+ (Settings Sync became built-in)
  • A GitHub account or Microsoft account
  • Multiple machines where you want consistent settings
  • Basic familiarity with VS Code settings

What Gets Synchronized

Settings Sync handles seven categories of configuration data:

1. Settings (settings.json)
2. Keyboard Shortcuts (keybindings.json)
3. Extensions
4. User Snippets
5. UI State (panel layouts, view states)
6. Profiles
7. Tasks (tasks.json — optional, added in recent versions)

Each category can be individually toggled on or off. This is important because not everything should sync. You might want different terminal fonts on different operating systems, or certain extensions only make sense on specific machines.

Enabling Settings Sync

Initial Setup

  1. Click the gear icon in the bottom-left corner
  2. Select "Settings Sync is Off" → "Turn On..."
  3. Choose what to sync (all categories are selected by default)
  4. Sign in with GitHub or Microsoft account
  5. VS Code uploads your current settings

Or use the Command Palette:

Ctrl+Shift+P → "Settings Sync: Turn On..."

Choosing an Account

GitHub and Microsoft accounts both work. The choice matters for a few reasons:

GitHub account:

  • Natural choice if you already use GitHub daily
  • Settings data stored in GitHub's infrastructure
  • Easier if your organization uses GitHub SSO

Microsoft account:

  • Works even without a GitHub account
  • Settings data stored in Microsoft's infrastructure
  • Required if your organization blocks GitHub authentication

You can only use one account at a time. Switching accounts later requires turning off sync, signing out, and signing in with the new account.

First Sync on a Second Machine

  1. Install VS Code on the new machine
  2. Turn on Settings Sync
  3. Sign in with the same account
  4. VS Code downloads and applies your synced settings
  5. Extensions begin installing automatically

The first sync on a new machine can take a few minutes if you have many extensions. VS Code installs them in the background — you can start working while they install.

Handling Conflicts

When the same setting has been changed on two machines before either syncs, VS Code shows a merge dialog:

┌──────────────────────────────────────────┐
│  Settings Sync: Merge Required           │
│                                          │
│  Local setting differs from remote.      │
│                                          │
│  editor.fontSize                         │
│  Local:  16                              │
│  Remote: 14                              │
│                                          │
│  [Accept Local] [Accept Remote] [Merge]  │
└──────────────────────────────────────────┘

Three resolution options:

  • Accept Local — keep the value from this machine, overwrite remote
  • Accept Remote — use the value from the other machine
  • Merge — opens a diff editor where you choose line by line

Conflicts are rare in practice. They happen most often during initial setup when two machines have significantly different configurations.

Machine-Specific Settings

Not every setting should be the same on every machine. Font sizes differ between a 4K desktop monitor and a laptop screen. Terminal paths differ between Windows and macOS. Extensions for C++ development are unnecessary on a machine used only for web development.

Platform-Specific Settings

VS Code supports platform-specific settings natively. These do not conflict during sync:

{
  "editor.fontSize": 14,

  "[linux]": {
    "editor.fontSize": 16,
    "terminal.integrated.defaultProfile.linux": "zsh",
    "terminal.integrated.fontFamily": "'JetBrains Mono', monospace"
  },

  "[windows]": {
    "editor.fontSize": 15,
    "terminal.integrated.defaultProfile.windows": "Git Bash",
    "terminal.integrated.fontFamily": "'Cascadia Code', monospace"
  },

  "[darwin]": {
    "editor.fontSize": 14,
    "terminal.integrated.defaultProfile.osx": "zsh",
    "terminal.integrated.fontFamily": "'SF Mono', monospace"
  }
}

Platform-specific blocks sync across all machines but only apply on the matching OS. This is the cleanest way to handle cross-platform differences.

Ignoring Specific Settings from Sync

Some settings should never sync. Add them to the ignore list:

// settings.json
{
  "settingsSync.ignoredSettings": [
    "editor.fontSize",
    "window.zoomLevel",
    "terminal.integrated.fontFamily",
    "http.proxy",
    "http.proxyStrictSSL",
    "remote.SSH.remotePlatform"
  ]
}

These settings remain local to each machine. Changes to them are never uploaded or downloaded.

Common candidates for ignoring:

editor.fontSize              Different monitors need different sizes
window.zoomLevel             Display-dependent
terminal.integrated.fontFamily  Font availability varies
http.proxy                   Network-specific
http.proxyStrictSSL          Network-specific
remote.SSH.remotePlatform    Machine-specific SSH hosts
files.associations           Project-specific overrides

Ignoring Extensions from Sync

Prevent specific extensions from being installed on other machines:

{
  "settingsSync.ignoredExtensions": [
    "ms-vscode.cpptools",
    "ms-python.python",
    "ms-vscode-remote.remote-wsl"
  ]
}

This is useful when some machines do not need language-specific tooling. A machine used exclusively for Node.js development does not need the C++ extension pack.

Ignoring Keybindings

You cannot ignore individual keybindings, but you can choose not to sync keybindings at all if your machines use different operating systems and you prefer OS-native shortcuts.

Toggle keybinding sync: Settings Sync: Configure... → uncheck "Keyboard Shortcuts".

Profiles for Different Workflows

VS Code Profiles let you maintain completely separate configurations for different types of work. Each profile has its own settings, extensions, keybindings, and snippets.

Creating Profiles

Ctrl+Shift+P → "Profiles: Create Profile..."

Name the profile and choose what to copy from the current configuration:

Profile Name: "Web Development"
Copy from: Default Profile

Include:
  [x] Settings
  [x] Keyboard Shortcuts
  [x] Extensions
  [x] User Snippets
  [x] UI State
  [x] Tasks

Profile Examples

Lightweight Editing Profile:

  • Minimal extensions (just Git and a theme)
  • Large font size for presentations
  • Zen mode enabled
  • No linters or formatters

Node.js Development Profile:

  • ESLint, Prettier, npm Intellisense
  • Debug configurations for Node
  • Terminal set to bash/zsh
  • Jest and testing extensions

Data Analysis Profile:

  • Jupyter extension
  • Python extension
  • Database client
  • CSV viewer

Writing Profile:

  • Markdown extensions
  • Spell checker
  • Distraction-free settings
  • Word wrap enabled

Switching Profiles

Ctrl+Shift+P → "Profiles: Switch Profile"

Or click the profile icon in the bottom-left (gear menu) to switch.

Profile Sync

Profiles sync across machines automatically when Settings Sync is enabled. Create a profile on your desktop, and it appears on your laptop within minutes.

Each profile syncs independently. Changing settings in the "Web Development" profile does not affect the "Data Analysis" profile on any machine.

Exporting and Sharing Profiles

Share profiles with team members:

Ctrl+Shift+P → "Profiles: Export Profile..."

Export options:

  • GitHub Gist — creates a private gist with the profile data
  • Local File — saves a .code-profile file

Import on another machine or by a team member:

Ctrl+Shift+P → "Profiles: Import Profile..."

Paste the gist URL or select the file.

Sync Status and Troubleshooting

Checking Sync Status

Ctrl+Shift+P → "Settings Sync: Show Synced Data"

This opens a view showing:

  • Last sync time for each category
  • What was synced in each direction
  • Conflict history
  • Remote data stored in the cloud

Viewing Sync Logs

Ctrl+Shift+P → "Settings Sync: Show Log"

The sync log shows every operation:

[2026-02-13 10:30:15] Info: Syncing Settings...
[2026-02-13 10:30:16] Info: Updated remote settings.
[2026-02-13 10:30:16] Info: Syncing Extensions...
[2026-02-13 10:30:17] Info: No changes to sync.
[2026-02-13 10:30:17] Info: Syncing Keyboard Shortcuts...
[2026-02-13 10:30:18] Info: Downloaded remote keyboard shortcuts.

Manual Sync Trigger

Settings Sync runs automatically, but you can force a sync:

Ctrl+Shift+P → "Settings Sync: Sync Now"

Resetting Sync Data

If sync gets into a bad state — duplicate extensions, conflicting settings, corrupted data:

Ctrl+Shift+P → "Settings Sync: Reset Synced Data"

This clears all remote data. The next sync uploads your current local configuration as the new baseline.

Warning: This affects all machines. The next time another machine syncs, it will download this new baseline and may lose settings that were only on that machine.

Complete Working Example: Team Onboarding Configuration

Here is a complete setup for synchronizing VS Code configuration across a development team, using profiles and shared settings.

Step 1: Create a Base Profile

// Export this profile as a GitHub Gist for team sharing
// Profile: "Team Standard"

// settings.json
{
  "editor.tabSize": 2,
  "editor.formatOnSave": true,
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.rulers": [80, 120],
  "editor.bracketPairColorization.enabled": true,
  "editor.guides.bracketPairs": "active",
  "editor.minimap.enabled": false,
  "editor.renderWhitespace": "boundary",
  "editor.suggestSelection": "first",
  "editor.linkedEditing": true,

  "files.trimTrailingWhitespace": true,
  "files.insertFinalNewline": true,
  "files.exclude": {
    "**/node_modules": true,
    "**/.git": true,
    "**/dist": true,
    "**/coverage": true
  },

  "search.exclude": {
    "**/node_modules": true,
    "**/dist": true,
    "**/package-lock.json": true
  },

  "terminal.integrated.scrollback": 10000,

  "git.autofetch": true,
  "git.confirmSync": false,
  "git.enableSmartCommit": true,

  "eslint.validate": [
    "javascript",
    "javascriptreact",
    "typescript",
    "typescriptreact"
  ],

  "[javascript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[json]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[markdown]": {
    "editor.wordWrap": "on",
    "editor.quickSuggestions": {
      "other": false,
      "comments": false,
      "strings": false
    }
  },

  "settingsSync.ignoredSettings": [
    "editor.fontSize",
    "window.zoomLevel",
    "terminal.integrated.fontFamily",
    "http.proxy"
  ]
}

Step 2: Define Required Extensions

// .vscode/extensions.json — committed to each project repo
{
  "recommendations": [
    "dbaeumer.vscode-eslint",
    "esbenp.prettier-vscode",
    "humao.rest-client",
    "christian-kohler.npm-intellisense",
    "christian-kohler.path-intellisense",
    "streetsidesoftware.code-spell-checker",
    "eamodio.gitlens",
    "usernamehw.errorlens"
  ],
  "unwantedRecommendations": []
}

Step 3: Workspace Settings for Projects

// .vscode/settings.json — committed to each project repo
// These override user settings for this project specifically
{
  "editor.tabSize": 2,
  "editor.formatOnSave": true,
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "files.eol": "\n",

  "eslint.workingDirectories": [{ "mode": "auto" }],

  "search.exclude": {
    "**/node_modules": true,
    "**/dist": true,
    "**/build": true,
    "**/.next": true
  },

  "files.watcherExclude": {
    "**/node_modules/**": true,
    "**/.git/objects/**": true,
    "**/dist/**": true
  }
}

Step 4: New Developer Onboarding Script

// scripts/setup-vscode.js
// Run this on a new developer's machine to set up the team configuration

var fs = require("fs");
var path = require("path");
var childProcess = require("child_process");

var requiredExtensions = [
  "dbaeumer.vscode-eslint",
  "esbenp.prettier-vscode",
  "humao.rest-client",
  "christian-kohler.npm-intellisense",
  "christian-kohler.path-intellisense",
  "streetsidesoftware.code-spell-checker",
  "eamodio.gitlens",
  "usernamehw.errorlens"
];

function getInstalledExtensions() {
  try {
    var output = childProcess.execSync("code --list-extensions", {
      encoding: "utf-8"
    });
    return output.trim().split("\n").map(function(ext) {
      return ext.toLowerCase();
    });
  } catch (err) {
    console.error("Could not list VS Code extensions:", err.message);
    return [];
  }
}

function installExtension(extensionId) {
  try {
    console.log("Installing " + extensionId + "...");
    childProcess.execSync("code --install-extension " + extensionId, {
      encoding: "utf-8",
      stdio: "pipe"
    });
    console.log("  Installed: " + extensionId);
  } catch (err) {
    console.error("  Failed to install " + extensionId + ": " + err.message);
  }
}

function run() {
  console.log("Setting up VS Code for team development...\n");

  var installed = getInstalledExtensions();
  var missing = requiredExtensions.filter(function(ext) {
    return installed.indexOf(ext.toLowerCase()) === -1;
  });

  if (missing.length === 0) {
    console.log("All required extensions are already installed.");
  } else {
    console.log("Installing " + missing.length + " missing extensions:\n");
    missing.forEach(function(ext) {
      installExtension(ext);
    });
  }

  // Check for workspace settings
  var vscodePath = path.join(process.cwd(), ".vscode");
  if (!fs.existsSync(vscodePath)) {
    console.log("\nWarning: No .vscode directory found in this project.");
    console.log("Expected workspace settings at: " + vscodePath);
  } else {
    var settingsPath = path.join(vscodePath, "settings.json");
    if (fs.existsSync(settingsPath)) {
      console.log("\nWorkspace settings found: " + settingsPath);
    } else {
      console.log("\nNo workspace settings.json found.");
    }
  }

  console.log("\nSetup complete. Restart VS Code to apply changes.");
  console.log("\nNext steps:");
  console.log("  1. Turn on Settings Sync (Ctrl+Shift+P -> 'Settings Sync: Turn On')");
  console.log("  2. Sign in with your GitHub account");
  console.log("  3. Import the team profile from the shared gist");
}

run();

Step 5: Onboarding Documentation

## New Developer VS Code Setup

1. Install VS Code from https://code.visualstudio.com/
2. Clone the project repository
3. Run the setup script:
   ```bash
   node scripts/setup-vscode.js
  1. Enable Settings Sync:
    • Ctrl+Shift+P -> "Settings Sync: Turn On..."
    • Sign in with your GitHub account
  2. Import the team profile:
    • Ctrl+Shift+P -> "Profiles: Import Profile..."
    • Paste this gist URL: [team gist URL]
  3. Open the project folder in VS Code
  4. Accept the recommended extensions prompt

## Managing Settings at Scale

### The Settings Hierarchy

VS Code applies settings in this order (later overrides earlier):
  1. Default Settings (VS Code defaults)
  2. User Settings (synced across machines)
  3. Remote Settings (remote-specific overrides)
  4. Workspace Settings (per-project, committed to repo)
  5. Workspace Folder Settings (per-folder in multi-root workspaces)

Understanding this hierarchy prevents confusion. A setting in workspace `settings.json` always overrides the same setting in your user configuration. This means project-specific formatting rules work correctly even if your personal preferences differ.

### Settings JSON vs. GUI

The Settings GUI (`Ctrl+,`) is convenient for browsing options, but the JSON file is the source of truth. Always check the JSON when debugging settings issues:

Ctrl+Shift+P → "Preferences: Open User Settings (JSON)"


### Portable Mode

For machines where you cannot use Settings Sync (air-gapped environments, shared workstations), VS Code supports portable mode:

```bash
# Create a portable installation
# 1. Download VS Code zip (not the installer)
# 2. Extract to a folder
# 3. Create a 'data' folder next to the VS Code executable

vscode/
  bin/
  data/              # <-- Create this folder
    user-data/       # Settings, extensions stored here
    extensions/
  resources/

In portable mode, all settings and extensions stay in the data folder. Copy the entire VS Code directory to a USB drive or network share.

Dotfiles Integration

If you maintain a dotfiles repository, you can integrate VS Code settings:

# In your dotfiles setup script

# Symlink VS Code settings
VSCODE_DIR="$HOME/.config/Code/User"
mkdir -p "$VSCODE_DIR"

ln -sf "$DOTFILES/vscode/settings.json" "$VSCODE_DIR/settings.json"
ln -sf "$DOTFILES/vscode/keybindings.json" "$VSCODE_DIR/keybindings.json"
ln -sf "$DOTFILES/vscode/snippets" "$VSCODE_DIR/snippets"

# Install extensions from a list
while IFS= read -r extension; do
  code --install-extension "$extension"
done < "$DOTFILES/vscode/extensions.txt"
# vscode/extensions.txt
dbaeumer.vscode-eslint
esbenp.prettier-vscode
eamodio.gitlens
humao.rest-client
streetsidesoftware.code-spell-checker
christian-kohler.npm-intellisense

This approach works alongside Settings Sync or as an alternative for environments where cloud sync is not available.

Common Issues and Troubleshooting

Settings Sync shows "Turning on sync failed"

Authentication failed or network issues prevented sync from starting:

Fix: Sign out completely (Settings Sync: Turn Off), restart VS Code, and sign in again. If behind a corporate proxy, configure http.proxy in settings before enabling sync. Check that your GitHub or Microsoft account has not been deactivated.

Extensions keep reinstalling after being removed

Settings Sync restores extensions you uninstalled because the remote data still lists them:

Fix: Add the extension to settingsSync.ignoredExtensions before uninstalling it. Or uninstall it, wait for sync to complete, then check "Show Synced Data" to verify the remote list was updated.

Settings from one machine overwrite another

Both machines edited the same setting offline, and the last one to sync won:

Fix: Use settingsSync.ignoredSettings for machine-specific settings like font size and zoom level. Use platform-specific blocks ([linux], [windows], [darwin]) for OS-dependent values. After a conflict, use "Show Synced Data" to review what changed.

Sync is slow or seems stuck

Large extension lists or many snippets can slow sync:

Fix: Check the sync log (Settings Sync: Show Log) for errors. Disable and re-enable sync. If the problem persists, reset synced data and let it re-upload from scratch. Remove extensions you no longer use — fewer extensions means faster sync.

Profiles do not appear on other machines

The profile was created but sync has not run yet:

Fix: Force a sync with Settings Sync: Sync Now on both machines. Profile sync requires VS Code v1.75+ on all machines. Older versions do not support profile synchronization.

Workspace settings override synced user settings

A project's .vscode/settings.json overrides your preferred formatting or editor behavior:

Fix: This is by design. Workspace settings intentionally override user settings so that project standards apply consistently. If you disagree with a project setting, discuss it with the team rather than overriding it locally.

Best Practices

  • Enable Settings Sync on every machine immediately. The longer you wait, the more settings drift accumulates. Set it up on day one.
  • Use platform-specific blocks instead of ignoring settings. [linux], [windows], and [darwin] blocks let you define per-OS values that sync cleanly. Ignoring a setting means managing it manually on each machine.
  • Keep the ignored settings list small. Only ignore settings that truly must differ between machines of the same OS: proxy settings, zoom level on specific monitors, and similar hardware-dependent values.
  • Use profiles for different workflows, not different machines. Profiles are for "I do web development and data science" — not for "this is my laptop config." Machine differences should use platform blocks and ignored settings.
  • Commit .vscode/settings.json and .vscode/extensions.json to your repos. This ensures everyone on the team gets project-specific settings and extension recommendations without manual setup.
  • Review synced data periodically. Use "Show Synced Data" to audit what is being synchronized. Remove stale snippets, unused extensions, and outdated keybindings.
  • Export your profile as a backup. Even with cloud sync, having a local export of your profile means you can recover from a sync reset or account issue.
  • Set up a team profile for onboarding. A shared profile gist eliminates the "set up your editor" step for new team members. Update it when team standards change.

References

Powered by Contentful