VS Code is a shell. Every useful feature a data creator relies on — Python language server, dbt LSP, Databricks Connect debugger, Copilot — comes from an extension. Understanding the ecosystem is a prerequisite for running a paved path that does not drift, leak, or rot.
What an extension is
An extension is a package that registers contributions against VS Code's extension API. Contributions fall into categories:
- Languages. Syntax highlighting, bracket matching, folding rules. Tiny, fast-loading, usually safe.
- Language servers (LSP). Separate processes that provide IntelliSense, diagnostics, hover, and refactoring. Pylance, dbt LSP, SQLFluff, and most modern language extensions are LSP-backed.
- Debuggers (DAP). Processes that attach to a running program via the Debug Adapter Protocol. debugpy, the Node debugger, and the Databricks debug adapter fit here.
- Tree views and webviews. UI panels in the side bar or editor area. Webviews are HTML+JS surfaces running in a sandboxed process; GitLens, the Databricks extension, and most rich UIs use them.
- Commands and keybindings. New palette entries, new shortcuts.
- Tasks and problem matchers. Declared command invocations with error parsing.
An extension can contribute any combination. The Databricks extension, for example, contributes a tree view, commands, a task provider, and a debug adapter.
Where extensions live
Three locations, different trust levels:
| Source | Who publishes | Trust |
|---|---|---|
| Visual Studio Marketplace (marketplace.visualstudio.com) | Microsoft and third parties | Default. Microsoft operates light review. |
| Open VSX (open-vsx.org) | Community | Used by VSCodium, Theia, and some VS Code forks. Less curated. |
| VSIX sideload | Anyone | Trust is entirely on you. Sometimes necessary for internal extensions or air-gapped shops. |
VS Code (the Microsoft build) defaults to the Marketplace. Cursor and most VS Code forks default to Open VSX. Extension IDs overlap between the two but publishers can and do differ.
The supply chain you inherit
Installing an extension runs untrusted code on your laptop. Extensions have full filesystem access, network access, and terminal access. A compromised extension can exfiltrate your SSH keys, AWS credentials, and source code before you open the next file.
This has happened. In 2024, a popular theme extension shipped a malicious update that harvested developer credentials. In 2025, a "dbt helper" extension was flagged for stealing warehouse credentials from ~/.dbt/profiles.yml. The pattern repeats.
Warning
Every extension you install is a supply-chain dependency. Treat the list the same way you treat requirements.txt: pinned, reviewed, and audited. If you would not paste a random pip install URL from the internet, do not click-install a random extension either.
Version pinning and reproducibility
By default, VS Code auto-updates extensions when new versions appear. That is fine for a hobby setup and catastrophic for a team that needs reproducible builds.
Three mitigations, in increasing rigor:
- Workspace recommendations.
.vscode/extensions.jsonwith arecommendationsarray. VS Code prompts new contributors to install them. It does not pin versions but gets everyone to the same list. - Extension pack. A published VS Code extension whose sole contribution is
extensionPack— a list of other extensions. Installing the pack installs the list. The pack version itself can be pinned; new entries require a new pack release. - Paved-path setup script. An idempotent script that runs
code --install-extension <id>@<version>for every extension. Checked into the paved-path repo. Run on every onboarding and in CI for devcontainer builds.
Tip
Combine (2) and (3). Publish an Extension Pack for day-to-day contributor use. Use the setup script for devcontainers and CI where reproducibility is non-negotiable.
Disabling auto-update
In user settings:
{
"extensions.autoUpdate": false,
"extensions.autoCheckUpdates": true
}
Auto-check stays on so you see what is available. Auto-update goes off so the act of updating is a deliberate action. Review release notes before clicking.
Reading an extension's permissions
VS Code does not have a mature permission-prompt system the way browsers do. Extensions ask for broad scopes and get them. Evaluate an extension before installing:
- Publisher and verification. Marketplace shows a blue check for verified publishers. Prefer those.
- Install count. Popular is not the same as safe, but a 50K-install extension has more eyes on it than a 50-install one.
- Repository link. Extensions with linked public repos are auditable. Extensions without them are not.
- Change log. A maintained extension has visible activity. A stale one may have unpatched vulnerabilities.
- Permissions it uses. Check
package.jsonin the repo:activationEvents,contributes.commands, and the code it runs. A "theme" that reads your filesystem is a red flag.
Publisher reputation
The safe publishers as of 2026:
- Microsoft (
ms-*IDs): Python, Pylance, Jupyter, Remote-Containers, Remote-SSH. The baseline. - Major vendors (
databricks.*,dbtLabsInc.*,HashiCorp.*,GitHub.*): first-party extensions from the companies whose products they integrate. High trust. - Well-known community maintainers (
eamodio.gitlens,charliermarsh.ruff,redhat.vscode-yaml): years of reputation, large install bases, active repos. - Platform teams' own published extensions: the paved-path extension pack and any internal extensions.
Anyone else warrants scrutiny. "I found this handy extension yesterday" is the beginning of most supply-chain incidents.
Governance in an org
A responsible org extension policy has three layers:
- An allow-list. Extensions the org has audited and approved. Published via the paved-path Extension Pack.
- A deny-list. Extensions known to behave badly or that duplicate approved tooling. Blocked via
extensions.blockListor an EDR policy. - A review queue. A channel (issue tracker, form, Slack) where engineers propose additions to the allow-list. Platform reviews, adds.
Important
Do not run the allow-list as a bottleneck. If proposals take weeks to review, engineers route around the policy by installing extensions anyway. Aim for a two-day review SLA and staff it.
Devcontainers and extensions
Devcontainer extensions live in the devcontainer's customizations.vscode.extensions array. They install inside the container on first open. Since the container is reproducible, extensions are effectively pinned through it — if you rebuild the devcontainer, you rebuild the extension set.
Combine devcontainers with the paved-path Extension Pack: the devcontainer installs the Pack, the Pack installs the extensions. One source of truth for the full set.
When to write your own
Platform teams sometimes publish internal extensions:
- Organization-specific language support (e.g., a custom DSL for your data catalog).
- A paved-path Extension Pack that bundles the approved set.
- Tooling against internal services that a marketplace extension cannot know about.
The barrier is low — yo code scaffolds a TypeScript extension — but the ongoing maintenance is not. Default to configuring marketplace extensions well before writing new ones.
Anti-patterns
The failure modes that trip up teams:
- "Install whatever you like." Every laptop ends up with a different toolchain; reproducing a teammate's bug becomes impossible.
- "Disable the extension policy for this week." The temporary exception becomes permanent. Extensions that entered the allow-list this way never leave.
- Mixing user config into the Extension Pack. The pack installs themes, icon sets, and personal conveniences along with the working extensions. Personal preferences belong in Settings Sync, not the repo.
- Not disabling auto-update. A breaking extension release lands on Friday afternoon; the whole team's CI goes red on Monday.
The maintenance cadence
A healthy Extension Pack gets reviewed quarterly. Questions to answer:
- Which extensions did the team stop using? Remove them.
- Which extensions have better replacements? Swap them.
- Which extensions rolled major versions? Pin them to a tested version if you haven't already.
- Which extensions have unresolved security issues? Escalate or drop.
A paved-path pack that has not been reviewed in a year is a paved-path pack that no longer reflects reality.
See also
- The extension pack reference — every extension ID the paved path ships.
- Settings reference — the settings each extension introduces.
- Workspace standards — the rules a workspace must satisfy.
- AI agents — Copilot, Continue, and Cline as extensions.