# microsoft/vscode-extension-samples: a reference set of VS Code extension examples

> The repository holds one self-contained extension per VS Code API topic, each with its own README, demo image and API listing. It is a reference library for people who already know what they want to build.

**microsoft/vscode-extension-samples** — Sample code illustrating the VS Code extension API.

- Repository: https://github.com/microsoft/vscode-extension-samples
- Stars: 10,179 · Forks: 3,897
- Language: TypeScript
- License: MIT
- Published: 2026-09-21 · Updated: 2026-09-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/microsoft-vscode-extension-samples

## What the samples repository actually contains

This is not a framework and not a starter kit. It is a collection of small extensions, each sitting in its own top-level folder, and each one demonstrates a single topic in the VS Code API or in the contribution points system. The README states that every sample is self-contained and that you can read, play with or adapt from them.

The README also states what you can expect from each sample: an explanation of its functionality, a gif or screenshot, a link to a guide on the VS Code website where one exists, a listing of the VS Code API and contribution points it uses, and code in a consistent style enforced with ESLint. That last point is the practical difference between this and copying snippets from a blog post. The samples are held to a shared style, and the repository ships scripts to compile, lint and format them all.

Who it is for: developers who have decided to build an extension and need to see how a particular API is wired up in a complete, runnable project. The folder names map directly to API surfaces, so the table in the README works as an index. If you want to know how a tree view is registered, there is a tree-view-sample. If you want a task provider, there is a task-provider-sample. The repository does not teach extension development from zero; the README points to the VS Code website guides for that.

## One folder per topic, and how the shared tooling is wired

The architecture is flat and deliberately repetitive. Each sample is an independent npm project with its own package.json and its own extension manifest. There is no shared runtime library that the samples import, which is why you can open any single folder in VS Code and run it without touching the rest of the repository.

At the root there is a package.json, but it is marked private and its version is 0.0.1. It is not published and it is not the extension you install. Its scripts operate on the collection as a whole, running a command or a script across the sample folders. The devDependencies are the tooling for that: tsx to run the TypeScript scripts, glob to find the folders, typescript, and the Node type definitions. The sample code itself is TypeScript, which matches the repository's primary language.

The .base-sample directory is the interesting part of the layout. The samples share a common base, and the repository carries a validate script plus an update-readme script, which suggests the README's sample table is generated rather than hand-edited. There is also an update-lsif script and an .lsifrc.json at the root, so the repository indexes its own code for navigation. None of this is required to use a sample. It matters only if you intend to contribute one or to keep a fork in sync.

## Installing the samples and running your first extension

The README gives the prerequisites plainly: node and npm must be installed. It recommends using the node version that VS Code development itself uses, which is documented on the VS Code wiki rather than pinned in this repository. There is no version manager file at the root, so the node version is your choice to make and the samples may or may not match it.

The usage section is four steps. Clone the repository, open any sample folder in VS Code, run npm install in the terminal, then press F5 to run the sample. The README also notes that each sample's own README may give different setup and run instructions, so the per-sample document wins when the two disagree.

Start with the hello world sample. It is the one the README links to the Extension Anatomy guide, and it is the smallest complete extension in the set.

```bash
git clone https://github.com/Microsoft/vscode-extension-samples
code helloworld-sample
```

Inside that folder, install dependencies from the terminal. This is a per-sample install, not a root install.

```bash
npm install
```

Then press F5 in VS Code. That launches an Extension Development Host, a second VS Code window running your extension. The README describes F5 as the run step for the samples generally. What you should see is the second window opening with the sample's contribution active, which for hello world is a command registered by the extension. If you want the JavaScript version instead of TypeScript, helloworld-minimal-sample is the one the README describes as the minimal Hello World written in JavaScript.

If you would rather work across the whole repository at once, the root package.json exposes scripts that fan out over the folders.

```bash
npm run install-all
npm run compile-all
npm run lint-all
```

install-all runs npm install in each sample, compile-all runs the compile script in each, and lint-all runs the lint script. Expect these to take a while and to fail on individual samples if your node version does not match what a given sample expects.

## Where the samples stop being useful

The samples are demonstrations, not production templates. Nothing in the repository describes packaging, publishing to the Marketplace, or release automation for your own extension. The root package.json has no package or publish script, and the README does not document an upgrade path between VS Code API versions. When the API changes, a sample either gets updated in the repository or it does not; there is no compatibility matrix here to tell you which samples target which engine version. That is exactly the kind of thing you have to check per sample.

The per-sample README is also the only place some information lives. The top-level README's sample table lists API and contribution points, but it does not repeat the setup instructions, and it does not cover every folder in the repository. The repository has folders such as chat-tutorial and lm-api-tutorial that are not in the getting started list. If a folder you care about is missing from the table, the table is not the source of truth.

There is a second mismatch worth naming. The repository is a reference, so it optimises for showing one API in isolation. Real extensions combine a manifest, activation events, configuration, and several providers at once. Adapting a sample means doing that integration work yourself, and the samples will not warn you when two of them make incompatible assumptions about activation or about the extension host. This is the wrong tool if what you want is a single opinionated project layout to build on top of.

## How this differs from a generator or a single template

The obvious alternative is a scaffolding generator, which produces one project skeleton with your extension's name already in the manifest and a build pipeline attached. The difference in approach is the direction of the work. A generator answers "give me a starting point" and you fill in behaviour. This repository answers "show me how this API behaves" and you extract the part you need.

That distinction has practical consequences. With a generator you get one layout and one set of tooling choices, and you inherit them. With the samples you get dozens of small projects that each make their own choices, which is more to read but also more to compare. If you are unsure whether a completion provider should use languages.registerCompletionItemProvider with a snippet or return plain items, the completions-sample is a worked answer, while a generator would have given you an empty registration and no opinion.

The samples also cover ground a general template usually does not: language server protocol variants, notebook renderers, chat participants, file system providers, and authentication providers. A generic scaffold tends to cover the hello world case and stop. The trade-off is that none of these samples is maintained as a dependency you can pull in. You copy code, and you own it from that moment.

## Licence, maintenance and what a fork costs you

The repository is MIT licensed, and the LICENSE file sits at the root. MIT is permissive: it allows use, modification and redistribution provided the copyright notice and permission notice are retained. That is a summary of the licence text, not legal advice, and if you are redistributing adapted sample code inside a commercial extension you should read the LICENSE file and the notices it requires rather than relying on this paragraph.

The practical licence question is attribution. Because the samples are meant to be adapted, code lifted from them ends up inside your extension, and the MIT notice needs to travel with it. The repository does not include a per-file header convention that would make this automatic, so it is on you to record where a piece of code came from.

On maintenance, the last push to the default branch was on 2026-09-05. For a repository of this size, with samples tracking an API that ships on its own schedule, that is the number that matters more than any label. There are no releases, and the root version is 0.0.1 and private, so there is no versioned artifact to depend on and no changelog to read for breaking changes. Upgrading means re-reading the sample you copied and diffing it against your own code. The repository ships validate, compile-all and lint-all scripts, which is what a fork would run to check that the collection still holds together after you add or edit a sample.

## Conclusion

Adopt it if you are writing a VS Code extension and want a working reference for a specific API surface, such as window.createWebviewPanel, tasks.registerTaskProvider or workspace.registerFileSystemProvider, rather than prose documentation. Skip it if you want a single scaffolded project to ship, because each folder is a demo and the root package.json is marked private with no build output of its own. Before you copy a sample, open that sample's own README and check which API and contribution points it lists, since the top-level README only points at the folders.

## FAQ

### What is a VS Code extension?

It is a package that adds functionality to VS Code through the extension API and the contribution points system. The README describes each sample in this repository as a self-contained extension that explains one topic in the VS Code API or in contribution points.

### How do I run a sample from microsoft/vscode-extension-samples?

Clone the repository, open any sample folder in VS Code, run npm install in the terminal, then press F5. The README notes that individual samples may give their own setup and run instructions, which take precedence.

### What do I need installed before running the samples?

The README lists node and npm as prerequisites and recommends the node version used for VS Code development, which is documented on the VS Code wiki rather than pinned in this repository. There is no version file at the root, so you choose the version yourself.

### Can I install the whole microsoft/vscode-extension-samples repository at once?

The root package.json is private and has no install script for the collection as a whole, but it exposes install-all, compile-all and lint-all, which run the corresponding command in each sample folder. These operate on the samples; they do not produce a single extension.

### Which sample should I start with in microsoft/vscode-extension-samples?

The README lists the Hello World sample first and links it to the Extension Anatomy guide. A minimal JavaScript version is in helloworld-minimal-sample, and a version with extension integration tests is in helloworld-test-sample.

### Are the samples in microsoft/vscode-extension-samples production templates?

No. Each sample is a self-contained extension demonstrating one topic, and there is no packaging or publishing script in the root package.json. Adapting a sample into a shippable extension is work you do yourself.

## Sources

- [Issues](https://github.com/microsoft/vscode-extension-samples/issues)
- [License: MIT](https://github.com/microsoft/vscode-extension-samples/blob/main/LICENSE)
- [microsoft/vscode-extension-samples on GitHub](https://github.com/microsoft/vscode-extension-samples)
- [README](https://github.com/microsoft/vscode-extension-samples/blob/main/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/microsoft-vscode-extension-samples
