Engineering Journal
Ginexys
Ginexys

Postmortem: Shipping Five VS Code Extensions to Marketplace in One Session

2026-06-03

TLDR

Shipping our five-extension suite (ginexys-core, ginexys-tafne, ginexys-pdf, ginexys-schema, ginexys-pack) to the VS Code Marketplace was planned as a 30-minute release task. It turned into a 5-hour engineering session due to monorepo symlink leaks (55MB artifacts), runtime cross-extension require() crashes, and global package name collisions.
Publishing IncidentRoot CauseEngineering RemediationFinal Resolution Time
55MB Bundle Bloatvsce package followed pnpm workspace symlinksAdded ../<sibling>/* & ../../ to .vscodeignore1 hour
Post-Install require() Crashtafne imported core via node_modules symlinkRefactored to vscode.extensions.getExtension().exports2.5 hours
Global Name Rejectionname: "core" was taken globally on MarketplaceRenamed package to ginexys-core & refactored references1.5 hours

Extension development hosts hide runtime packaging differences

Prior to release day, our extension suite had been thoroughly tested inside VS Code's Extension Development Host (F5). All five packages compiled cleanly via pnpm -r compile, inter-extension communication worked smoothly, and webviews rendered flawlessly.

However, compilation proving internal consistency is not the same as packaging proving external artifact consistency. F5 development relies on local workspace symlinks; the Marketplace relies on isolated, unpacked .vsix archives.


Sequenced release-day failures block initial deployment

We hit three sequential failure modes during release:

  Release Engineer               vsce package tool           Marketplace Registry
         |                               |                             |
         |--- 1. vsce package ----------->|                             |
         |<-- 2. 55MB Bloated Bundle ----|                             |
         |--- 3. Fix .vscodeignore (216KB)                               |
         |                                                             |
         |--- 4. Test production install ----------------------------->|
         |<-- 5. Runtime Error (Cannot find module 'core/...') --------|
         |--- 6. Fix: Refactor to activate-exports API                  |
         |                                                             |
         |--- 7. vsce publish "core" --------------------------------->|
         |<-- 8. HTTP 400 (Name 'core' already taken globally) --------|
         |--- 9. Rename to ginexys-core & publish successfully ------->|

1. Monorepo artifact bloat

The initial vsce package in packages/core produced a 55 MB package containing all sibling extension directories, root configuration files, and build scripts. Fix: Configured explicit relative ignore rules (../core/, ../../) in .vscodeignore, bringing the package size down to 216 KB.

2. Runtime extension sandboxing violations

In production, VS Code installs each extension into an isolated sandboxed directory. The compiled TafneEditorProvider.js contained require("core/webview/html-rewriter"), which threw Module not found in production because node_modules symlinks do not exist post-install.

3. Global name collisions

Marketplace rejected name: "core" because the name property is globally unique across all publishers in the registry.

Decoupled monorepos support scalable multi-extension suites

Once the deployment artifacts were properly structured, the core engine logic executed flawlessly:

Rule of thumb: Test your deployment packaging workflow (vsce package) on day one of development. Never wait until release day to discover monorepo symlink leaks or cross-package runtime resolution failures.

Read this post in the full Engineering Journal →