Targeted slices of VSCode's full structural dependency graph — structural findings from a well-maintained, large-scale TypeScript codebase
I analyzed the VSCode repository with PViz and used it as a stress test for a new slicing feature.
At the time of analysis, the VSCode graph had:
- 10,311 nodes
- 92,011 dependency edges
- ~72 MB readable architecture bundle
- ~23 MB compressed bundle
The full bundle includes the dependency graph, file metadata, structural metrics, and architectural signals in one artifact. That completeness matters, but it creates a practical problem: a 72 MB JSON bundle is not something you hand to a reviewer or an LLM and expect useful output.
Slicing is a new PViz feature designed specifically for codebases at this scale. Rather than working from the full bundle directly, slicing derives targeted architectural views from it — no re-parsing, no re-scanning.
For this showcase, the full bundle produced 15 focused artifacts:
- edge-summary / edge-list
- node-summary / node-list
- hub-summary
- SCC summary / SCC list / SCC graph
- blast-radius
- directory metrics / directory structure
- test summary / test coverage / test list
- entry candidates
Sizes range from 2 KB to 3 MB — none exceeds 5% of the source bundle.The slice feature is currently in beta. Larger slices benefit from an initial LLM summarization pass; the smaller orientation slices are directly readable.
These are the findings that came out of it.
The graph is cleaner than you might expect
For a codebase of this scale and age, the dependency signal is remarkably clean. The vast majority of edges are static TypeScript imports - the graph is essentially the module resolution layer made explicit. Dynamic imports, reexports, and CommonJS require calls together account for a small fraction of total edges. One self-edge, zero malformed edges. Conclusions drawn from the topology are conclusions about the static module structure, not runtime behavior.
Two opposite architectural risk profiles
The most interesting structural finding isn't a single number - it's that two very different risk profiles coexist in the same graph.
The first is coupling risk. The largest SCC contains 204 files spanning chat, notebooks, and terminal. These three product areas are not independently refactorable. Changes in one require awareness of the other two. The component has substantial internal edges plus significant incoming and outgoing external edge traffic - it is a major architectural knot, not a local file cycle. This is the kind of structural entanglement that accumulates gradually and becomes expensive to unwind.
The second is dependency concentration risk. The src/vs/base/common SCC tells the opposite story. Almost the entire codebase depends into it; it depends outward almost nowhere. That asymmetry is not a coupling problem - it is a fragility-at-the-foundation problem. Changing anything in that cluster has a blast radius that is difficult to bound precisely because so much of the codebase sits above it.
Both are architectural risks. They look nothing alike and require completely different responses.
Architectural gravity
The hub analysis separates two kinds of architectural centers. Incoming hubs are platform contracts - foundational files that large portions of the codebase depend on. Outgoing hubs are composition roots - files that pull many modules together into feature registration or session assembly points. Neither is inherently problematic, but they are the files where architectural decisions have the most leverage and where change carries the most risk.
At the directory level, src/vs/base/common is the dominant gravity center for the entire codebase, absorbing the largest share of incoming dependency edges by a significant margin.
Blast radius
The blast-radius slice lets you target a specific file, set traversal direction (incoming or outgoing), and configure depth and node/edge caps. For this showcase, processes.ts was chosen as an arbitrary test case to demonstrate the feature - no particular significance to that file beyond being a low-level utility.
Tracing its incoming dependents at depth 4 hit the configured 500-node cap before exhausting the full neighborhood, crossing base/node, platform, server, workbench, terminal, diagnostics, process explorer, and extension host. Zero SCCs touched - the risk here is breadth of dependents, not cycle entanglement. Running the same slice on a different file, direction, or depth would produce a completely different output from the same bundle.
The SCC distribution
143 non-trivial SCCs in total. The majority are small - 2 to 5 files - which is what you'd expect from a well-maintained codebase where most cyclic risk is local and bounded. The tail is where structural debt has accumulated: a handful of large feature clusters in the 26 to 200-file range that would require coordinated effort across multiple areas to untangle.
The distribution tells a reasonable story for a codebase of this age and scale: disciplined in the small, accumulated complexity in the large.
On the methodology
This is a slice-based structural analysis, not a comprehensive audit. Each slice derives from the same completed canonical bundle but answers a different architectural question. The findings reflect what the static dependency graph reveals - not runtime behavior, test coverage, or code quality. Blast radius numbers reflect configured caps, not exhaustive traversal.
Full showcase with all 15 downloadable slice artifacts and the PDF report at VS Code Showcase.