microsoft / workspaces2

Monolith to Platform

How Canvas became @canvas/shell

The Frame

workspaces2's Canvas grew organically — and this is the refactor that turned that monolith into a platform

In microsoft/workspaces2, the Canvas handled every project type inline. Each new type meant more hardcoded conditionals and a fatter core card. Two connected efforts — a project-type plugin architecture (#338) and an extracted @canvas/shell package (#368/#370/#373/#376) — rebuilt it as a real platform.

First, how bad was the organic growth? The numbers are on the record.

The organic growth was measurable, not rhetorical

ADR 015 documents project-type logic that had spread as hardcoded conditionals. A direct count of the frontend before #338 confirms the sprawl firsthand.

And the component that absorbed all this logic paid the price…

130+
scattered project-type conditional locations (ADR 015)
42
agentType === checks in the frontend alone, pre-#338

The core CanvasCard paid the price and couldn't scale

CanvasCard swelled as every project type was wired in by hand. It peaked at 1455 lines after the shadcn/ui migration (#207) and still sat at 450 lines just before the refactor began.

So the team stopped growing the monolith and started building a platform.

1455
CanvasCard peak lines after shadcn/ui (#207)
450
lines just before the refactor (#329 baseline)

#338 turned CanvasCard into a thin window manager

The project-type plugin architecture (#338, 2026-02-06) moved view-specific logic into self-contained plugins. Per the design doc, CanvasCard became "a thin window manager that delegates all view-specific logic to autonomous plugin components" — cutting it 450 → 147 in a single PR.

With plugins in place, the shared shell could finally be extracted.

450→147
CanvasCard lines, in one PR (#338)
plugins
self-contained per project type; card just manages the window

A four-PR arc extracted the Canvas UI into a shared @canvas/shell package

#368/#370/#373/#376 (2026-02-08 to 02-11) pulled CanvasWorkspace, CanvasCard, Dock and Header into @canvas/shell — a project-agnostic package described as a "minimal canvas shell for card-based layouts."

How was a change this large actually carried out?

156
files in the extraction PR (#368); 31,621 insertions
80-90%
code copied from the real canvas, not rewritten
28
test files inside the extracted package

The platform work was AI/agent-assisted with Amplifier

Amplifier is the agent-assisted development toolset used across this arc. ADR 015 is authored "AI-assisted," 38 commits repo-wide carry "Generated with Amplifier," and the work ran across multiple documented sessions — e.g. a ~6-hour Canvas Shell session on 2026-02-07 — over roughly 5 days.

The payoff: what the core card looks like now.

38
commits carry "Generated with Amplifier"
~6 hrs
documented Canvas Shell session, 2026-02-07
~5 days
span of the platform PRs, #338 to #376

The result is an 89-line thin window manager

The organically-grown monolith is now a reusable @canvas/shell platform. Across the arc the core CanvasCard was cut 450 → 89 lines — from a hand-wired catch-all down to a thin window manager at HEAD.

There's a repeatable pattern hiding in that number.

89
CanvasCard lines at HEAD (#376) — down from 450 across the arc

The pattern generalizes: shared shell out, variation into plugins

Organic sprawl becomes an owned, testable platform when you separate what's common from what varies.

The audit trail for every number is next.

Sources

Research Methodology

Data as of: 2026-02-11 — microsoft/workspaces2 @ HEAD 509ac63

Feature status: Project-type plugin architecture — Implemented / merged (#338); @canvas/shell — Shipped, 28 test files, integrated via #373/#376; CanvasCard thin window manager — Achieved (89 lines at HEAD).

Verified against: microsoft/workspaces2 (clone at /tmp/ws2). The bundle repo michaeljabbour/amplifier-bundle-graph-canvas contains no canvas-platform code; all canvas facts come from workspaces2.

Commands run:

Gaps: Topic-prompt figures (319→83, 2,508 tests, three laptop crashes, 317 turns, "Superpowers," two-day/10-session) were independently confirmed fabricated/unsupported and excluded. Platform work spans ~5 days (Feb 6–11), not two.

Primary contributors: singh2 (5 commits) and Ken Chau (5 commits) in the #338–#376 arc; Johanna Hawkins (Ortiz) authored ADR 015 & the CanvasCard refactoring design doc (AI-assisted, 2 commits); cpark4x (2 commits); Amplifier co-authored 38 commits repo-wide.

More Amplifier Stories