Skip to main content

Development Environment Setup

VS Code provides a comprehensive development environment with pre-configured tasks, launch configurations, and tooling.

Editor Configuration

The repository includes VS Code workspace settings optimized for development:

TypeScript

  • Tabs for indentation (not spaces)
  • Real-time compilation feedback
  • Strict type checking enabled

Tasks

  • Pre-configured build tasks
  • Watch mode tasks
  • Test runner tasks

Extensions

  • ESLint integration
  • TypeScript language features
  • Debug adapters

Launch Configs

  • Multiple debug configurations
  • Compound launch setups
  • Test runner integrations

Architecture Overview

Understanding the codebase structure is essential for effective development:

Core Source Structure (src/)

src/vs/base/ - Foundation utilities and cross-platform abstractions
  • Common data structures (arrays, maps, events)
  • Platform-agnostic utilities
  • Basic UI components
  • No dependencies on other VS Code layers

Built-in Extensions

The extensions/ directory contains first-party extensions:
  • Language features: typescript-language-features/, html-language-features/, css-language-features/
  • Core features: git/, debug-auto-launch/, emmet/, markdown-language-features/
  • Themes: theme-* folders
  • Development tools: extension-editing/, vscode-api-tests/

Coding Guidelines

Following these guidelines is mandatory for all code contributions. The CI/CD pipeline enforces many of these rules.

Naming Conventions

// Use PascalCase for types
type ViewMode = 'split' | 'single';

// Use PascalCase for interfaces
interface IEditorService {
    activeEditor: IEditor;
}

// Use PascalCase for enum values
enum Theme {
    Light,
    Dark,
    HighContrast
}

Indentation and Style

VS Code uses tabs, not spaces for indentation. This is enforced by ESLint.
// Correct: No parens for single parameter
array.map(x => x + 1)

// Correct: Parens for multiple parameters
array.map((x, y) => x + y)

// Correct: Parens for type parameters
array.map(<T>(x: T) => x)

// Wrong: Unnecessary parens
array.map((x) => x + 1)

String Handling

import * as nls from 'vs/nls';

// Use double quotes for user-facing strings
const message = nls.localize('key', "This message will be translated");

// Use placeholders instead of concatenation
const error = nls.localize('error', "Failed to open {0}", fileName);

UI Labels

Use title-style capitalization for UI elements:
// Command labels (title case)
const command = {
    id: 'workbench.action.files.openFile',
    title: 'Open File',  // ✓ Correct
    // title: 'Open file',  // ✗ Wrong
};

// Don't capitalize short prepositions
'Show in Explorer'  // ✓ Correct
'Show In Explorer'  // ✗ Wrong

Code Quality Requirements

1

TypeScript Strictness

  • No any or unknown without justification
  • Proper type annotations required
  • Define interfaces for complex types
// Good
function processData(data: EditorData): Result {
    return transform(data);
}

// Avoid
function processData(data: any): any {
    return transform(data);
}
2

Async/Await

Prefer async/await over Promises:
// Preferred
async function loadFile(uri: URI): Promise<string> {
    const content = await fileService.readFile(uri);
    return content.value.toString();
}

// Avoid
function loadFile(uri: URI): Promise<string> {
    return fileService.readFile(uri).then(content => {
        return content.value.toString();
    });
}
3

Disposables

Critical: Always handle disposables properly to avoid memory leaks:
class MyComponent {
    private readonly disposables = new DisposableStore();

    constructor() {
        // Register disposables immediately
        this.disposables.add(
            this.onDidChange(() => this.update())
        );
    }

    dispose(): void {
        this.disposables.dispose();
    }
}
4

Code Reuse

Always search for existing utilities before implementing new ones:
// Check if similar functionality exists in:
// - src/vs/base/common/
// - src/vs/base/browser/
// - src/vs/platform/*/common/

Development Tasks

Compilation and Building

# Start all watch tasks in parallel
npm run watch

# Or start specific watch tasks
npm run watch-client
npm run watch-extensions

Code Quality Checks

Run these checks before committing:
1

TypeScript Compilation

Check for compilation errors:
npm run compile
Monitor the watch task output for real-time errors:
npm run watch
2

Layer Validation

Ensure architectural layers are respected:
npm run valid-layers-check
3

Linting

Run ESLint and StyleLint:
npm run eslint
npm run stylelint
4

Hygiene Check

Run all code hygiene checks:
npm run hygiene
Or use the precommit hook:
npm run precommit

Specialized Compilation Checks

npm run monaco-compile-check

Working with Extensions

Building Extensions

# Compile all built-in extensions
npm run compile-extensions-build

# Watch extensions for changes
npm run watch-extensions

Downloading Built-in Extensions

Some extensions are not included in the repository:
# Download all built-in extensions
npm run download-builtin-extensions

# Download with code generation
npm run download-builtin-extensions-cg

Updating Dependencies

Grammar Updates

Update language grammars:
npm run update-grammars

Localization

Update localization extension:
npm run update-localization-extension

TypeScript Version

Update to latest TypeScript:
npm run update-build-ts-version

Performance Testing

Run performance benchmarks:
# Performance tests
npm run perf

# Using scripts
node scripts/code-perf.js

Common Development Workflows

Feature Development

1

Start Watch Mode

npm run watch
2

Run VS Code

Launch VS Code with debugger attached (F5 in VS Code) or:
./scripts/code.sh
3

Make Changes

Edit TypeScript files - they’ll automatically recompile
4

Reload Window

In the running VS Code instance:
  • Press Cmd/Ctrl + R to reload
  • Or use Command Palette: “Developer: Reload Window”
5

Run Tests

Test your changes:
./scripts/test.sh --grep "your test pattern"

Bug Fixing Workflow

1

Find Related Code

  1. Use semantic search for general concepts (Glob tool)
  2. Use grep for exact strings/error messages
  3. Follow imports to understand dependencies
  4. Check test files for usage patterns
2

Debug the Issue

Launch VS Code with debugger (see Debugging)
3

Implement Fix

Make changes following coding guidelines
4

Validate

# Check compilation
npm run compile

# Run tests
./scripts/test.sh --grep "related test"

# Check layers
npm run valid-layers-check

CI/CD Integration

The repository includes CI/CD scripts:
npm run core-ci        # Full core CI
npm run core-ci-pr     # PR checks

Tips and Best Practices

Always develop with watch mode running (npm run watch) for instant feedback on TypeScript errors.
Use the pre-configured launch configurations in .vscode/launch.json for debugging different processes:
  • Main Process
  • Extension Host
  • Shared Process
  • Search Process
Before importing from another module, verify it’s allowed by the layer architecture:
npm run valid-layers-check
Run relevant tests frequently during development:
./scripts/test.sh --grep "pattern matching your feature"
If you encounter strange issues, try a clean build:
rm -rf out node_modules/.cache
npm run compile

Next Steps

Debugging

Learn how to debug VS Code itself

Running Tests

Understand the testing infrastructure

Building from Source

Review build instructions

How to Contribute

Read the full contribution guide