Building tools. Learning to build tools. Learning to build learning tools.
How to bundle, distribute, and extend the extension.
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.
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.
To publish to the VS Code Marketplace:
Marketplace (Manage) scope. This authenticates vsce
for publishing.
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.
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.
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 |
If you want to push further, here are some ideas:
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.
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.