Overview

VS Code works out of the box with TypeScript but degrades on large projects without explicit configuration. This guide adds a .vscode/settings.json that pins the workspace TypeScript version, wires the formatter, configures import organization, and reduces editor noise from irrelevant files. The result is accurate type errors, fast go-to-definition, and consistent formatting on save. See typescript for the tsconfig.json conventions.

Prerequisites

  • VS Code with the default TypeScript extension (ms-vscode.vscode-typescript-next for the latest engine, or the built-in for stability).
  • A tsconfig.json at the project root.
  • TypeScript installed as a dev dependency: npm add -D typescript or pnpm add -D typescript.

Steps

1. Create .vscode/settings.json

.vscode/settings.json applies workspace-level settings that override user defaults. Commit this file so all contributors get consistent settings.

{
  "typescript.tsdk": "node_modules/typescript/lib",
  "typescript.enablePromptUseWorkspaceTsdk": true,
  "editor.formatOnSave": true,
  "editor.defaultFormatter": "biomejs.biome",
  "[typescript]": { "editor.defaultFormatter": "biomejs.biome" },
  "[typescriptreact]": { "editor.defaultFormatter": "biomejs.biome" },
  "editor.codeActionsOnSave": {
    "source.organizeImports": "explicit",
    "source.fixAll.biome": "explicit"
  },
  "typescript.preferences.importModuleSpecifier": "relative",
  "typescript.updateImportsOnFileMove.enabled": "always",
  "files.exclude": {
    "node_modules": true,
    "dist": true,
    ".next": true,
    "public": true
  },
  "search.exclude": {
    "node_modules": true,
    "dist": true,
    "pnpm-lock.yaml": true
  }
}

Replace biomejs.biome with esbenp.prettier-vscode if the project uses Prettier instead of Biome.

2. Pin the workspace TypeScript version

"typescript.tsdk": "node_modules/typescript/lib" tells VS Code to use the project’s installed TypeScript version rather than the built-in one. This ensures the editor and CI use the same compiler.

On first open, VS Code prompts to use the workspace TypeScript. Click Allow or enable typescript.enablePromptUseWorkspaceTsdk to automate this.

Verify the active version in the status bar at the bottom right. It should match typescript in package.json.

Create .vscode/extensions.json to prompt contributors to install the right extensions.

{
  "recommendations": [
    "biomejs.biome",
    "ms-vscode.vscode-typescript-next",
    "bradlc.vscode-tailwindcss",
    "dbaeumer.vscode-eslint"
  ]
}

Contributors see a prompt to install recommended extensions when they open the project.

4. Configure tsconfig.json for editor performance

On large projects, exclude directories that the editor does not need to type-check.

{
  "compilerOptions": {
    "strict": true,
    "noUncheckedIndexedAccess": true,
    "target": "ES2022",
    "moduleResolution": "bundler",
    "paths": {
      "@/*": ["./src/*"]
    }
  },
  "exclude": ["node_modules", "dist", ".next", "public"]
}

"moduleResolution": "bundler" matches Vite and Next.js module resolution behavior. See swc-vs-babel for how this affects the build.

5. Use project references for monorepos

In a monorepo, each package should have its own tsconfig.json and the root should have a tsconfig.json with references. This allows VS Code to provide accurate cross-package type checking.

// Root tsconfig.json
{
  "files": [],
  "references": [
    { "path": "./packages/ui" },
    { "path": "./packages/api" },
    { "path": "./apps/web" }
  ]
}

Run tsc --build to compile with project references. VS Code uses the references to resolve imports across packages.

Verify it worked

Open a TypeScript file and confirm:

  1. Hovering a variable shows the inferred type.
  2. Saving auto-formats the file and organizes imports.
  3. The TypeScript version in the status bar matches the project’s installed version.
  4. Renaming a symbol across files updates all references automatically.
# Confirm workspace TypeScript version
cat node_modules/typescript/package.json | grep '"version"'

The version should match what VS Code reports in the status bar.

Common errors

  • Editor uses wrong TypeScript version: typescript.tsdk is not set, or the path is wrong. Verify node_modules/typescript/lib exists with ls node_modules/typescript/lib/typescript.js.
  • Format on save does nothing: the formatter extension is not installed, or "editor.defaultFormatter" is set to an extension ID that does not match the installed extension. Check View > Extensions for the correct ID.
  • Imports not organizing: source.organizeImports requires the TypeScript language service to be active on the file. Ensure the file’s language mode is TypeScript, not JavaScript.
  • Go-to-definition jumps to .d.ts instead of source: add "declarationMap": true to tsconfig.json. This generates source maps for declarations so go-to-definition resolves to the original .ts file.
  • Type errors in editor not matching tsc output: the editor is using a different tsconfig.json than tsc. Add "typescript.tsconfig.autoDetect": "on" and check which config the status bar reports.