130 Widgets

Building tools. Learning to build tools. Learning to build learning tools.

9. Packaging, Publishing & Next Steps

How to bundle, distribute, and extend the extension.

Packaging with vsce

vsce (Visual Studio Code Extensions) is the official CLI for packaging and publishing VS Code extensions. Install it globally:

npm install -g @vscode/vsce

Then package the extension into a .vsix file:

vsce package

This runs vscode:prepublish (which compiles the TypeScript), bundles the compiled JavaScript, package.json, and any other included files into a single .vsix archive. The result is something like color-identity-0.1.0.vsix.

You can install the .vsix locally:

code --install-extension color-identity-0.1.0.vsix

Or share it with others by sending them the file. No Marketplace account needed for local distribution.

Controlling What Gets Bundled

A .vscodeignore file (similar to .gitignore) controls what’s excluded from the .vsix bundle. You typically exclude source files, test files, and development configuration:

.vscode/**
src/**
node_modules/**
.gitignore
tsconfig.json
**/*.ts
**/*.map

The compiled out/ directory and package.json are always included. The goal is a minimal bundle: users don’t need your TypeScript source or development tooling.

Publishing to the Marketplace

To publish to the VS Code Marketplace:

  1. Create a publisher: Sign in at marketplace.visualstudio.com/manage with a Microsoft or GitHub account and create a publisher ID.
  2. Create a Personal Access Token (PAT): In Azure DevOps, create a token with the Marketplace (Manage) scope. This authenticates vsce for publishing.
  3. Login and publish:
    vsce login your-publisher-id
    vsce publish

After publishing, the extension appears in the Marketplace and can be installed by anyone searching for it in VS Code’s Extensions view.

Tip

You can also publish pre-release versions with vsce publish --pre-release. Pre-release versions are shown separately in the Marketplace and let you test with early adopters before promoting to a stable release.

What We Built

Let’s take stock of what Color Identity covers in 690 lines:

Concept Where
Extension manifest and activation package.json, Section 1
Shared type contracts types.ts, Section 2
Deterministic string hashing (djb2) colorGenerator.ts, Section 3
HSL color space and theme-aware generation colorGenerator.ts, Section 4
Safe workspace settings merging colorApplier.ts, Section 5
QuickPick UI with icons and input flow colorPicker.ts, Section 6
PNG encoding, DEFLATE, CRC-32 swatchGenerator.ts, Section 7
Event-driven lifecycle and reactivity extension.ts, Section 8

Ideas for Extending

If you want to push further, here are some ideas:

Architecture Note

The extension’s modular design makes all of these additions straightforward. Git branch colors would change getEffectiveHue. Color history would add a storage layer and modify the picker. Multi-root awareness would change getWorkspaceName. None of these require restructuring the existing code — each module has a clear responsibility and a clean interface.

Closing Thoughts

Color Identity started as a simple question: “Can I tell my VS Code windows apart at a glance?” The answer turned out to involve more interesting computer science than expected — hashing algorithms, color theory, binary file formats, and event-driven architecture, all packed into six files with zero dependencies.

The zero-dependency constraint wasn’t an ideology — it was the natural outcome of the problem being small enough that every component could be built from first principles in less code than it would take to configure a library. That’s a good heuristic for dependency decisions in general: if you can build it in fewer lines than the import statement plus configuration, just build it.