← Archive
DemosBlogTry PViz
May 2026microsoft/vscodeTypeScriptJavaScriptRustslicingdependency-analysisarchitectureLLM context

VSCode: Turning a 72 MB Bundle into Focused Architecture Views

How PViz slicing extracts fifteen purpose-built analysis artifacts from a single canonical bundle — 10,311 nodes, 92,011 edges, ranging from 2 KB to 3 MB.

  • A single 72 MB PViz bundle becomes 15 focused architecture views, each under 5% of the source bundle.
  • VSCode's dependency graph is 99.5% static TypeScript imports across 92,011 edges.
  • 143 non-trivial SCCs — cyclic risk is concentrated in a 204-file chat/notebook/terminal component.
  • src/vs/base/common absorbs 17,723 incoming dependency edges — the dominant architectural gravity center.
  • Touching processes.ts reaches the 500-node cap across process, terminal, remote, extension host, and workbench infrastructure.
Nodes
10,311
Edges
92,011
Slices
15
Smallest slice share
<0.01%

Analysis report

The report is the narrative. The supporting files are the evidence.

Open report (PDF)

Evidence snapshots

Individual PViz bundles per version — download any snapshot for your own analysis.

edge-summary
PViz snapshot (.json)
edge-summary (compressed)
PViz snapshot (.json)
node-summary
PViz snapshot (.json)
node-summary (compressed)
PViz snapshot (.json)
scc-summary
PViz snapshot (.json)
scc-summary (compressed)
PViz snapshot (.json)
hub-summary
PViz snapshot (.json)
hub-summary (compressed)
PViz snapshot (.json)
test-coverage
PViz snapshot (.json)
test-coverage (compressed)
PViz snapshot (.json)
test-summary
PViz snapshot (.json)
test-summary (compressed)
PViz snapshot (.json)
entry-candidates
PViz snapshot (.json)
entry-candidates (compressed)
PViz snapshot (.json)
scc-list
PViz snapshot (.json)
scc-list (compressed)
PViz snapshot (.json)
blast-radius
PViz snapshot (.json)
blast-radius (compressed)
PViz snapshot (.json)
scc-graph
PViz snapshot (.json)
scc-graph (compressed)
PViz snapshot (.json)
directory-metrics
PViz snapshot (.json)
directory-metrics (compressed)
PViz snapshot (.json)
directory-structure
PViz snapshot (.json)
directory-structure (compressed)
PViz snapshot (.json)
test-list
PViz snapshot (.json)
test-list (compressed)
PViz snapshot (.json)
edge-list
PViz snapshot (.json)
edge-list (compressed)
PViz snapshot (.json)
node-list
PViz snapshot (.json)
node-list (compressed)
PViz snapshot (.json)
UI metrics (.json)
Small UI-ready summary payload
PViz schema [email protected]Metrics schema showcase-metrics@v1Generated 2026-05-07Published 2026-05-07

From one bundle to fifteen views

A full PViz bundle is the canonical source of truth. It preserves the complete dependency graph, file metadata, language coverage, structural metrics, and architectural signals in one artifact. For the VSCode repository, that bundle is 71,900 KB readable and 23,249 KB compressed, covering 10,311 nodes and 92,011 edges.

That completeness matters. But complete context is not the same as relevant context. Most architectural questions are narrower than the full repository — and handing a 72 MB artifact to an LLM or reviewer for a targeted question is impractical.

This is especially important for LLM-assisted code review. A full repository graph may exceed a practical context window or dilute the model's attention with unrelated evidence. Slicing lets the same completed analysis bundle be viewed from specific architectural angles: dependencies, hubs, SCCs, blast radius, tests, directories, or file inventory. The LLM does not need the entire 72 MB bundle to answer every question; it needs the right slice for the question being asked.

Slicing is the answer. A slice is a derived artifact generated from a completed bundle. It does not rescan the repository, rerun parsing, or reinterpret the project. It takes the full graph as the source of truth and extracts a focused view designed for a specific architectural question. For this showcase, PViz generated the VSCode bundle once, then produced fifteen distinct slice artifacts. The results range from 2 KB to 3,013 KB readable — every one of them under 5% of the source bundle.

The value of slicing is not simply that the JSON gets smaller. The value is that each artifact preserves the evidence needed for one architectural question while discarding unrelated context. That makes whole-codebase analysis more usable for humans and more practical for LLM workflows.

ℹ

Who this is for

This workflow is for developers, reviewers, and LLM-assisted analysis workflows that need whole-codebase architectural context without loading the whole-codebase artifact. The full bundle remains the source of truth, but each slice gives a bounded view of that source: enough structure to reason about one architectural question, small enough to fit into a practical review or LLM context window.

All fifteen slices at a glance

Readable and compressed sizes as a share of the 71,900 KB source bundle. All measurements use default slice settings.

SliceReadableCompressedSource sharePurpose
edge-summary2 KB2 KB<0.01%Dependency composition overview
node-summary6 KB4 KB0.01%File/codebase composition
scc-summary13 KB10 KB0.02%Cycle landscape summary
hub-summary50 KB29 KB0.07%Dependency centers
test-coverage95 KB73 KB0.13%Test touchpoint coverage
test-summary100 KB78 KB0.14%Test architecture summary
entry-candidates124 KB91 KB0.17%Graph entry / navigation points
scc-list138 KB108 KB0.19%Cyclic file membership list
blast-radius411 KB316 KB0.57%Targeted impact analysis
scc-graph718 KB530 KB1.00%SCC component topology and edge traffic
directory-metrics767 KB353 KB1.07%Directory-level code mass
directory-structure1,264 KB446 KB1.76%Navigable repo hierarchy
test-list2,683 KB1,554 KB3.73%Exhaustive test dependency rows
edge-list2,824 KB1,348 KB3.93%Exhaustive dependency edge list
node-list3,013 KB1,844 KB4.19%Exhaustive file inventory

Four families, four purposes

The fifteen slices fall into four families based on what they are optimized for.

Orientation and summary slices — edge-summary, node-summary, hub-summary, scc-summary, test-summary, test-coverage, entry-candidates, directory-metrics, and directory-structure — provide fast orientation and high signal-per-byte. Most are well under 1% of the source bundle. These are the right first-pass artifacts to give an LLM or reviewer before deciding what deeper analysis is needed.

List slices — node-list, edge-list, scc-list, and test-list — preserve exhaustive evidence. They are larger because they carry every record, but even the largest is under 5% of the full bundle. Their job is verification: after a summary identifies something worth investigating, the paired list provides the exact membership or edge detail.

Topology slices — scc-graph — answers the structural question of how cyclic regions connect to the rest of the codebase. It preserves component-level edge traffic, internal versus external edge counts, and top directory relationships for each major SCC. It is larger than scc-summary because it carries that traffic data.

Targeted slices — blast-radius — produce bounded answers around a user-selected file or module. The same source bundle can yield very different blast-radius outputs depending on target, direction, depth, and output limits.

The pairing rule: use the summary to orient, use the list to verify. node-summary and node-list are a pair; edge-summary and edge-list are a pair; scc-summary and scc-list are a pair. The three test slices serve distinct roles: test-summary describes the test graph at a high level; test-coverage focuses on production touchpoint coverage and untouched hotspots; test-list provides exhaustive test-to-production dependency rows. For cycle analysis, all three SCC slices form a progression: scc-summary to orient, scc-list for exact file membership, and scc-graph to understand how each cyclic region connects to the rest of the codebase.

Composition

The codebase at a glance

From node-summary and directory-metrics — before touching any dependency data.

The VSCode bundle contains 10,311 nodes, approximately 2.99 million lines of code, and approximately 2.32 million source lines of code. The codebase is overwhelmingly TypeScript-oriented: 9,402 TypeScript nodes, plus 262 TSX, 485 JavaScript, and 74 Rust, with smaller counts for MJS, CJS, and JSX. The repo-wide comment ratio is 9.65% and code density is 77.48%.

Most files are not individually large. The biggest bucket is 1 to 50 SLOC with 2,866 nodes, followed by 101 to 250 SLOC with 2,683 nodes. Only 312 nodes exceed 1,000 SLOC. VSCode's scale comes from a very large number of small-to-medium modules, not a few monolithic files.

Code mass is heavily concentrated in a few subtrees. The extensions subtree contains 3,739 files and approximately 34% of repository LOC. extensions/copilot alone accounts for 2,805 files and roughly 22.5% of repository LOC. That makes Copilot one of the dominant code-mass regions in this bundle — though some of that mass is data-heavy, generated, or fixture-oriented content rather than hand-authored application logic.

The largest single file in the bundle is a test fixture — extensions/vscode-colorize-perf-tests at 119,635 SLOC. Several other large files are grammar files, completion lists, and generated language data artifacts. The biggest files are not the most architecturally central files.

Largest files in the bundle

From node-summary composition data, not dependency topology. File size does not equal architectural importance — the top files by SLOC are fixtures, grammars, and generated data.

PathLOCFan-inFan-outNotes
extensions/vscode-colorize-perf-tests/.../test-checker.ts119635——Test fixture — not an architectural center
extensions/copilot/.../cuda-cpp.tmLanguage.ts19815——Grammar / language data
workbench/contrib/notebook/test/.../notebookDiffService.test.ts14623——Test file
extensions/copilot/.../multilineModelWeights.ts12312——Model weight data
workbench/services/search/test/.../employee.js11190——Search test fixture
extensions/terminal-suggest/src/completions/upstream/docker.ts6831——CLI completion data

Dependency analysis

Dependency composition from 2 KB

From edge-summary — 92,011 edges distilled into a 2 KB orientation artifact.

The VSCode dependency graph contains 92,011 edges across 8,589 source nodes, referencing 9,665 total nodes. The edge-summary slice captures the graph's dependency composition in 2 KB readable: edge kinds, source and target counts, malformed and self-edge checks, and the overall shape of how dependencies are represented. That is less than 0.01% of the readable source bundle. It does not replace the exhaustive edge-list; it gives the fastest orientation view before exact edge inspection.

The graph is overwhelmingly static-import driven. Approximately 99.5% of edges are plain import relationships. Reexports account for about 0.35%, dynamic imports for about 0.12%, and CommonJS require calls for about 0.03%. The slice also reports one self-edge and zero malformed edges — a useful quality signal.

Most source nodes use more than one outgoing dependency: 7,578 multi-edge sources versus 1,011 single-edge sources. But almost every source node uses only one edge kind — 98.8% of sources are single-kind sources. Dependency complexity in VSCode comes from the breadth of imports per file, not from mixing different relationship mechanisms inside individual files.

This matters for downstream analysis. Conclusions drawn from edge topology in the VSCode graph are conclusions about static TypeScript and JavaScript module imports — not runtime dynamic loading behavior.

Where architectural gravity lives

From hub-summary — incoming hubs vs. outgoing hubs.

The hub-summary slice reveals a clear split between two kinds of architectural centers in the VSCode graph.

Outgoing hubs are composition roots and feature registration points. These are files that pull many modules together: sessions.common.main.ts with 252 outgoing edges, workbench.common.main.ts with 245, chat.contribution.ts with 182, and various Electron and workbench startup files. They are orchestration surfaces.

Incoming hubs are foundational platform APIs. These are files that everything else depends on: lifecycle.ts with 2,653 incoming edges, uri.ts with 1,981, event.ts with 1,669, nls.ts with 1,657, and instantiation.ts with 1,569. They are platform contracts.

At the directory level, src/vs/base/common dominates incoming dependency concentration with 17,723 incoming edges and 17,937 total edges. That confirms it as the foundational shared utility layer — the surface most of the codebase depends into.

Neither kind of hub is inherently problematic. Incoming hubs reveal shared contracts — they are risky to change because many files depend on them. Outgoing hubs reveal coordination points — they are worth understanding when navigating or refactoring feature areas.

Top dependency hubs

Outgoing hubs are composition roots. Incoming hubs are platform contracts.

FileTypeEdge countNotes
sessions.common.main.tsOutgoing252 outSession assembly point
workbench.common.main.tsOutgoing245 outWorkbench composition root
chat.contribution.tsOutgoing182 outChat feature registration
lifecycle.tsIncoming2,653 inPlatform lifecycle API
uri.tsIncoming1,981 inURI utility — used everywhere
event.tsIncoming1,669 inEvent emitter primitive
nls.tsIncoming1,657 inLocalization API
instantiation.tsIncoming1,569 inDI container core

Cycle structure

143 non-trivial SCCs, but the risk is concentrated

From scc-summary and scc-list.

The VSCode bundle contains 143 non-trivial strongly connected components out of 8,689 total SCCs. Those non-trivial SCCs involve 1,119 files out of the full 10,311-node graph. With 39,129 edges touching non-trivial SCC regions, cyclic areas are not isolated pockets — they are heavily connected to the rest of the codebase.

Most cyclic components are small. Seventy-six SCCs contain exactly 2 files, 39 contain 3 to 5 files, and 10 contain 6 to 10 files. The risk profile is not evenly distributed — it concentrates in a small number of much larger clusters: 7 SCCs of 11 to 25 files, 8 SCCs of 26 to 50 files, and 3 SCCs of 51 or more files.

The SCC slices serve different jobs. scc-summary gives the compact cycle landscape: how many SCCs exist, how large they are, and where the largest clusters live. scc-list provides exact file membership for each non-trivial SCC. scc-graph adds topology and edge traffic, showing whether each cyclic component is isolated, heavily depended on, or broadly dependent on external directories.

The largest SCC contains 204 files and is centered in the workbench chat area. It extends across chat browser UI, notebook browser and view and model code, terminal, task handling, and chat-agent tooling. This component has 686 internal edges but also 759 incoming external edges and 3,834 outgoing external edges — 5,279 total touching edges. It is a major architectural knot, not a local file cycle.

A notably different profile appears in the 45-file src/vs/base/common SCC. It has only 174 internal edges, but 8,405 incoming external edges and just 75 outgoing external edges. Many parts of the codebase depend into it while it depends outward very little. This is a foundational utility knot, consistent with the hub-summary finding that base/common is the dominant architectural gravity center.

Cycle size distribution

Most cyclic components are small. A few large subsystem clusters carry the majority of cycle complexity.

Size bucketSCC countNotes
2 files76Small, often fixable in isolation
3-5 files39Small subsystem cycles
6-10 files10Medium-small clusters
11-25 files7Medium clusters
26-50 files8Large subsystem cycles
51+ files3Major feature clusters — 204, 90, and 55 files

Largest strongly connected components

Each entry is a cluster of files in a mutual dependency cycle. Fan-in and fan-out are external edges — not internal to the SCC.

PathLOCFan-inFan-outNotes
Chat / Notebook / Terminal (workbench contrib)744697593834204 files — largest architectural knot in the graph
Copilot command / prompt / tooling24189402122790 files — feature orchestration cluster
TypeScript language features93842222655 files — 31 dynamic imports internally
src/vs/base/common (core utilities)1005184057545 files — foundational utility knot; everything depends into it
extensions/copilot base/common (copy)986913447445 files — Copilot-bundled base utility layer
Copilot completions / prompt infrastructure560428518140 files — completions-core SCC

Targeted analysis

What does touching processes.ts affect?

From blast-radius — incoming direction, depth 4, max 500 nodes / 2,000 edges.

The blast-radius slice answers a specific change-planning question: if I modify this file, what parts of the codebase are nearby in the dependency graph? For this showcase, the target is src/vs/base/common/processes.ts.

With an incoming traversal at depth 4, the slice reached the configured cap of 500 reachable nodes, captured 1,026 reachable edges, touched 239 directories, and was marked truncated. The correct conclusion is not that this is the complete impact map; it is that the reachable incoming graph is at least this broad under the selected limits.

The immediate dependents show that processes.ts is a low-level process utility used by node process helpers, IPC, diagnostics, external terminal handling, platform process services, terminal monitoring, utility process handling, server and remote agent code, task services, terminal environment logic, and local extension host startup.

By depth 2 and 3, the dependency surface expands into Electron startup, shared process, agent host, extension host, file watchers, sandbox helpers, terminal and pty host infrastructure, remote server services, workbench task services, workbench terminal services, issue reporting, and test infrastructure. The impact area crosses base/node, platform, server, workbench, terminal, diagnostics, process explorer, and extension host — not a single subsystem.

The slice also reports zero touched SCCs. The target has a broad incoming surface but no cycle entanglement for this traversal. The risk profile is breadth of dependents, not cycle complexity.

ℹ

Truncated output

The blast-radius slice hit the 500-node cap before exhausting the full incoming neighborhood of processes.ts. The conclusion is that the reachable graph is at least this broad — not that this is a complete impact map. Re-run with higher limits or a shallower depth to control the trade-off between coverage and output size.

Where to start reading a 10,311-node graph

From entry-candidates.

The entry-candidates slice evaluates 7,618 production nodes across 73,755 edges after excluding tests and fixtures. It identifies two kinds of starting points.

Exact roots are files with zero incoming internal edges after filtering — deterministic graph origins. The slice found 515 of them. The top exact roots look like real architectural launch surfaces: sharedProcessMain.ts at 0 incoming and 140 outgoing, chatLibMain.ts at 0 and 119, sessions.desktop.main.ts at 0 and 111, workbench.desktop.main.ts at 0 and 100, and cliProcessMain.ts at 0 and 71. The list also includes extension entry files, build and gulp files, server and CLI files, platform host mains, and contribution-style modules.

Structural candidates are files with very low incoming counts and high outgoing counts — topology-based heuristics rather than proven entrypoints. The slice found 1,088 of them. They cluster in workbench feature directories: debug, SCM, MCP, API browser, preferences, testing, remote, terminal, and chat areas.

Neither list proves runtime entrypoint status. Together they give a reviewer or LLM a practical map before reading a single file.

Test architecture

Where the test graph touches production code

From test-summary — structural touchpoints, not runtime coverage.

The VSCode test graph contains 2,693 test nodes, including 415 fixture nodes, against 7,618 production nodes. The slice identifies 13,843 static dependency edges from tests to production files, while also observing 4,400 test-to-test edges that were excluded from output.

At the structural level, 2,666 production nodes are directly touched by test dependencies, while 4,952 production nodes have no direct test dependency edges. The most-touched production files are foundational shared modules: uri.ts is touched by 485 test files, lifecycle.ts by 366, event.ts by 268, and log.ts by 237. These are the same files that topped the incoming hub rankings — common platform utilities are not only widely imported by production code, they are also heavily referenced by tests.

The broadest test files are shared test service and helper modules rather than narrow single-feature tests. workbenchTestServices.ts has 175 outgoing production dependencies, and several Copilot test service files have 122, 84, and 74. This suggests VSCode's test structure includes reusable test harness layers that fan out across many production modules.

The untouched production areas include terminal completions, workbench API, debug, chat, Git, TypeScript language features, build, and Copilot prompt and tooling directories.

ℹ

Structural touchpoints vs. runtime coverage

This slice identifies which production files are directly depended on by test files as a static graph relationship. It does not prove behavioral coverage, infer test intent, or account for runtime instrumentation. Untouched means no direct static dependency edge was found from a test file to that production file — not that the area is unverified or unexercised at runtime.

Customization

Every slice is tunable

VSCode measurements in this showcase used default settings except where a slice requires a target or bounds. The blast-radius run used src/vs/base/common/processes.ts, incoming direction, depth 4, max 500 nodes, and max 2,000 edges. These measurements are baselines, not fixed outputs.

Each slice mode starts from the same completed source bundle but can be customized before export. All modes share common output controls: output format, output path, pretty-print toggle, and quiet mode.

Size controls limit detail level. Directory slices accept min_nodes and max_depth to filter out sparse or deeply nested directories. The test-list slice accepts max_edges to cap output row count.

Focus controls define the architectural target. The blast-radius mode is the clearest example: the same bundle produces very different outputs depending on the selected file, traversal direction, depth limit, and maximum node and edge counts. The processes.ts run in this showcase used depth 4 and a 500-node cap — running it shallower keeps output smaller, running it deeper increases coverage until the cap is hit.

Ranking controls affect summary density. Hub-summary, scc-graph, and entry-candidates all expose top_n options so the output stays compact while still surfacing the most structurally significant items.

The fifteen slices in this showcase are default-settings baselines. Every number reflects what PViz produces out of the box against the VSCode repository.

✓

The slicing workflow

Generate the bundle once. Derive the slice you need. Give the LLM only the structural view that answers the current question.