Visual Studio Code: Best Practices, Essential Extensions and a Productive Development Workflow
Visual Studio Code (VS Code) has become one of the most widely used code editors because it combines a lightweight interface with powerful debugging, Git integration, language tooling, remote development and extension support.
However, installing dozens of extensions does not automatically make a developer more productive. A well-configured editor should improve code quality, reduce repetitive work, support consistent team practices and avoid unnecessary resource consumption.
This article covers practical VS Code best practices, popular extensions, recommended configurations, security considerations and workflows for professional software development.
1. Understand the core features before installing extensions
VS Code already provides several essential capabilities:
- IntelliSense for supported programming languages.
- Integrated terminal and task execution.
- Source Control integration with Git.
- Debugging through launch configurations and language extensions.
- Search across files and folders.
- Code navigation, refactoring and symbol search.
- Settings, keyboard shortcuts, snippets and profiles.
- Remote development support through appropriate extensions.
2. Organise projects properly
Open the project root folder rather than individual source files. This allows VS Code to detect project configuration, Git repositories, language environments and workspace settings correctly.
A typical web application might use this structure:
my-application/
├── frontend/
├── backend/
├── tests/
├── docs/
├── scripts/
├── .github/
│ └── workflows/
├── .vscode/
│ ├── settings.json
│ ├── extensions.json
│ └── launch.json
├── .editorconfig
├── .gitignore
├── README.md
└── package.json
Not every project needs all these files. Use a structure appropriate to the language, framework and repository size.
Keep configuration in the right place
- User settings: personal preferences across projects.
- Workspace settings: project-specific editor behaviour.
- Language-specific settings: formatting and behaviour for a particular language.
.vscode/extensions.json: recommended extensions for the team..vscode/launch.json: shared debugging configurations..vscode/tasks.json: repeatable development tasks.
Avoid committing personal paths, credentials, machine-specific interpreter paths or local environment settings.
3. Use consistent formatting and linting
Formatting and linting solve different problems.
| Role | Purpose | Examples |
|---|---|---|
| Formatter | Standardises code layout, indentation, quotes and line wrapping. | Prettier, Ruff |
| Linter | Detects suspicious patterns, potential bugs and violations of coding rules. | ESLint, Ruff |
| Type checker | Identifies type inconsistencies before runtime. | TypeScript, Pylance |
| Tests | Validate expected behaviour. | pytest, Jest |
For example, a JavaScript or TypeScript project may use Prettier for formatting and ESLint for code analysis. A Python project may use Ruff for linting and formatting, alongside the project's chosen type checker.
Avoid configuring several formatters to compete for the same file type. Select a standard, document it and enforce it in CI where practical.
4. Recommended VS Code settings
The following is a reasonable starting point for many development projects. Adjust it to match the repository's conventions and installed tools.
Example .vscode/settings.json:
{
"editor.formatOnSave": true,
"editor.formatOnPaste": false,
"editor.codeActionsOnSave": {
"source.fixAll": "explicit",
"source.organizeImports": "explicit"
},
"editor.minimap.enabled": false,
"editor.renderWhitespace": "selection",
"editor.rulers": [100],
"editor.tabSize": 2,
"editor.insertSpaces": true,
"files.trimTrailingWhitespace": true,
"files.insertFinalNewline": true,
"files.eol": "\n",
"search.exclude": {
"**/node_modules": true,
"**/.git": true,
"**/dist": true,
"**/build": true
}
}
Important considerations:
- A two-space indentation setting is suitable for many JavaScript and JSON projects, but Python requires indentation consistent with its conventions. Language-specific settings can override the default.
formatOnSaveworks only when a formatter is configured for the file type.- Save-time code actions depend on installed extensions and their supported settings.
- Do not enable automatic fixes indiscriminately if they can alter code in ways the team has not reviewed.
- Excluding generated directories from search can improve usability, but do not exclude source files that need to be inspected.
Use EditorConfig
An .editorconfig file helps maintain consistent basic formatting across editors and IDEs.
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.py]
indent_style = space
indent_size = 4
[*.{js,jsx,ts,tsx,json,css,scss,yml,yaml}]
indent_style = space
indent_size = 2
[*.md]
trim_trailing_whitespace = false
EditorConfig complements formatters; it does not replace them.
5. Recommended VS Code extensions
The right extensions depend on your language and workflow. The following are established options worth evaluating, not a recommendation to install everything.
General development
| Extension | Role | Notes |
|---|---|---|
| Prettier - Code formatter | Formats supported files consistently. | JavaScript, TypeScript, JSON, CSS, HTML and Markdown. |
| ESLint | JavaScript and TypeScript linting within the editor. | Use the project's local ESLint configuration. |
| EditorConfig for VS Code | Applies basic formatting conventions defined in .editorconfig. | Complements formatters. |
| GitLens | Git history, line authorship information and commit exploration. | Useful for investigating changes in a large codebase. |
| Error Lens | Makes diagnostics more visible directly in the editor. | Can improve feedback speed; some may find it noisy. |
| Path Intellisense | Path completion while editing import statements. | Useful for file references. |
| Todo Tree | Locates comments such as TODO and FIXME. | Treat as reminders, not tracked work items. |
Python development
| Extension | Role | Notes |
|---|---|---|
| Python (Microsoft) | Interpreter selection, debugging integration and testing support. | Additional language components may be installed as needed. |
| Pylance (Microsoft) | Python IntelliSense, navigation and type-aware analysis. | Commonly used alongside the Python extension. |
| Ruff | Fast Python linting and formatting when configured. | Avoid overlapping lint and formatting tools. |
| Jupyter (Microsoft) | Notebooks and interactive workflows. | Data analysis, experimentation and machine learning. |
| Python Debugger (Microsoft) | Python debugging workflows. | Related components may install automatically. |
JavaScript, TypeScript and frontend
| Extension | Role | Notes |
|---|---|---|
| ESLint | JavaScript and TypeScript linting. | Enforces configured rules. |
| Prettier | Consistent formatting for frontend file types. | Project-configured. |
| Tailwind CSS IntelliSense | Class-name completion. | Tailwind CSS projects only. |
| Angular Language Service | Angular template diagnostics, completion and navigation. | Angular applications. |
| Volar / Vue - Official | Vue language support. | Use the extension recommended for the Vue version. |
| Live Server | Serves static files locally with browser reload. | Convenient for simple exercises; not a framework dev server. |
Backend, APIs and databases
| Extension | Role | Notes |
|---|---|---|
| REST Client | Sends HTTP requests from .http or .rest files. | Repeatable API tests; exclude secrets. |
| Docker | Container images, containers and Docker workflows. | Backend container development. |
| Remote - SSH | Connects to remote development hosts over SSH. | Files and terminal commands on the remote machine. |
| Dev Containers | Development inside a project-configured container. | Standardises dependencies and tooling. |
| SQLTools | Database connectivity and query workflows. | Verify driver compatibility and security. |
Cloud and infrastructure
| Extension | Role | Notes |
|---|---|---|
| HashiCorp Terraform | Terraform syntax support. | Validate infrastructure with Terraform CLI and CI pipeline. |
| AWS Toolkit | AWS-related development features. | Least-privilege IAM permissions. |
| Azure Resources | Browse and work with supported Azure resources. | Editor integration. |
| Kubernetes | Kubernetes resource workflows. | Confirm cluster context before applying changes. |
| YAML | YAML language support with validation. | Use schema validation where supported. |
Documentation and productivity
| Extension | Role | Notes |
|---|---|---|
| Markdown All in One | Markdown editing conveniences. | Shortcuts, list assistance and tables of contents. |
| Code Spell Checker | Identifies possible spelling errors. | Configure domain-specific vocabulary. |
| Better Comments | Highlights different categories of comments. | Use sparingly. |
| GitHub Pull Requests | Selected GitHub PR and issue workflows. | Complements, not replaces, branch protection. |
6. Extension selection cheat sheet
| Requirement | Extension to evaluate | Important note |
|---|---|---|
| Code formatting | Prettier | Keep project configuration consistent. |
| JavaScript linting | ESLint | Use repository rules. |
| Python development | Python + Pylance | Select the correct environment. |
| Python linting | Ruff | Avoid duplicate linting rules. |
| Git history | GitLens | Review changes and blame carefully. |
| API testing | REST Client | Do not commit credentials. |
| Containers | Docker | Validate images and runtime settings. |
| Remote Linux development | Remote - SSH | Protect SSH keys and host access. |
| Reproducible environments | Dev Containers | Review container configuration. |
| Terraform | HashiCorp Terraform | Run terraform validate and plan checks. |
| Kubernetes | Kubernetes | Confirm cluster context before applying changes. |
| Markdown | Markdown All in One | Useful for documentation-heavy projects. |
| Tailwind CSS | Tailwind CSS IntelliSense | Only needed for Tailwind projects. |
| Notebooks | Jupyter | Useful for data and ML workflows. |
Extension popularity and availability change over time. Check the current Visual Studio Marketplace listing, publisher, maintenance activity, compatibility and permissions before installation.
7. Manage extensions as part of your engineering process
Extensions can consume memory and CPU, introduce conflicts, access workspace files or execute code. Treat them as software dependencies.
Recommended practices:
- Install from the official Visual Studio Marketplace or an organisation-approved source.
- Verify the publisher and extension identifier.
- Review permissions, release notes, maintenance activity and known security issues.
- Install only extensions that solve a real problem.
- Disable extensions that are not relevant to the current profile.
- Avoid installing multiple extensions that perform the same task.
- Test important extensions after editor updates.
- Keep an eye on extension host performance.
- Use organisation policies or approved extension lists in managed environments.
- Remove abandoned extensions when suitable alternatives are available.
You can inspect extension IDs with:
code --list-extensions
Install a known extension by its identifier:
code --install-extension ms-python.python
These commands assume the VS Code code command is available in your terminal.
8. Use profiles for different roles
Profiles allow separate editor configurations for different kinds of work.
| Profile | Example extensions |
|---|---|
| Python and data science | Python, Pylance, Ruff, Jupyter. |
| Frontend | ESLint, Prettier, Tailwind CSS IntelliSense or framework-specific tooling. |
| Cloud and DevOps | Docker, Terraform, Kubernetes, YAML and cloud extensions. |
| Documentation | Markdown tooling and spelling assistance. |
| Minimal troubleshooting | A clean profile with only essential extensions. |
This avoids loading every extension into every workspace. Settings Sync can help keep supported preferences and profiles consistent across machines.
9. Git and team collaboration
Use VS Code's Source Control panel for routine Git operations, but understand the underlying Git commands.
Useful commands include:
git status
git diff
git diff --staged
git log --oneline --decorate -10
git switch -c feature/my-change
git add .
git commit -m "feat: add customer search"
git push -u origin feature/my-change
Before committing:
- Inspect the diff.
- Check that no secrets, generated files or local configuration have been staged.
- Run tests, linting and formatting checks.
- Write a meaningful commit message.
- Use a pull request for review when required by the project.
A .gitignore file should exclude appropriate generated files, local environments and secret-bearing files. However, .gitignore does not remove a secret that has already been committed. If a secret is exposed, revoke or rotate it promptly.
10. Debugging and testing best practices
Prefer the debugger over repeated print() or console.log() statements when investigating complex behaviour.
Use:
- Breakpoints to pause execution.
- Conditional breakpoints for specific conditions.
- The Variables and Watch panels to inspect state.
- The Call Stack to trace execution.
- Integrated terminals for test and build commands.
- Test integration where supported by your language extension.
Share project-level debug configurations through .vscode/launch.json when they are portable and safe. Avoid committing personal machine paths, tokens or sensitive environment values.
Editor debugging does not replace automated tests. Run the same test commands locally and in CI wherever possible.
11. Remote development and containers
For cloud and infrastructure engineers, remote development can reduce differences between local and target environments.
| Method | Use case |
|---|---|
| Remote - SSH | Work on a remote Linux or Unix host. |
| Dev Containers | Work inside a containerised development environment. |
| WSL | Use a Linux development environment on Windows. |
| Docker extension | Inspect and manage supported container workflows. |
Keep secrets outside the repository and use approved credential stores or environment injection. Never assume a container is secure merely because it isolates dependencies.
Before running tasks or scripts in an unfamiliar repository, review its configuration. VS Code Workspace Trust provides a Restricted Mode for potentially untrusted projects, but it is not a complete security boundary.
12. AI coding assistants: use them responsibly
AI coding tools can assist with code completion, explanations, tests, refactoring and debugging. They can also produce incorrect code, miss security concerns or make broad changes that are difficult to review.
Best practices:
- Follow your organisation's policy on AI tools and source-code sharing.
- Do not submit credentials, private keys, customer records or confidential data without explicit authorisation.
- Review generated changes as if they were written by another developer.
- Run tests, linters, type checks and security scans.
- Review dependency changes and shell commands before execution.
- Use small, reviewable changes rather than accepting large unverified edits.
- Treat instructions found in untrusted repositories and files as potentially malicious.
- Keep human review and approval for production changes.
AI assistance can accelerate development, but accountability for the resulting code remains with the engineering team.
13. Performance and productivity
A responsive editor is more useful than a heavily customised one that consumes excessive resources.
Recommended practices:
- Keep the number of active extensions small.
- Exclude large generated directories from search and file watching when appropriate.
- Avoid opening unnecessarily large parent directories as workspaces.
- Use the built-in Process Explorer and extension troubleshooting tools when performance degrades.
- Review large files, generated logs and bundled assets separately when needed.
- Use keyboard shortcuts and the Command Palette for repetitive operations.
- Use snippets for recurring code patterns.
- Learn multi-cursor editing, symbol navigation and workspace search.
- Use profiles to separate unrelated development environments.
| Action | Shortcut (Windows and Linux) |
|---|---|
| Command Palette | Ctrl+Shift+P |
| Quick Open | Ctrl+P |
| Search across files | Ctrl+Shift+F |
| Toggle terminal | Ctrl+` |
| Go to definition | F12 |
| Find references | Shift+F12 |
| Rename symbol | F2 |
| Format document | Shift+Alt+F |
| Toggle line comment | Ctrl+/ |
| Source Control view | Ctrl+Shift+G |
Shortcuts can differ by operating system, keyboard layout and custom keybindings.
14. Production-ready development checklist
Before considering a VS Code project setup ready for a professional team, verify the following:
- Project structure is documented.
- Formatting and linting rules are defined.
- Language and runtime versions are documented or pinned appropriately.
- Required extensions are recommended through
.vscode/extensions.json. - Workspace settings are minimal and portable.
- Secrets and machine-specific configuration are excluded from Git.
- Debug and task configurations do not expose sensitive information.
- Tests and validation commands are documented.
- CI enforces relevant linting, tests and build checks.
- Extension publishers and permissions have been reviewed.
- Untrusted repositories are inspected before execution.
- AI tooling complies with organisational policy.
- Production access follows least privilege.
- Changes are reviewed before merging and deployment.
Conclusion
VS Code is most effective when its built-in capabilities, extensions, project settings and development practices work together.
Start with a small extension set, establish consistent formatting and linting, use Git and automated tests, create profiles for different roles, and treat extensions and AI tools as part of your software supply chain.
Official resources
- VS Code documentation
- Extension Marketplace
- User and workspace settings
- Settings Sync
- Profiles
- Workspace Trust
- Extension Marketplace guide
- Python extension
- Pylance
My recommendation: Start with the extensions relevant to your current stack, such as Python/Pylance/Ruff, ESLint/Prettier, GitLens, Docker, Terraform and Remote - SSH. Add others only when a concrete development need justifies them.