pext-viz: from proof of concept to a real module for visualising converted control flow
pext-viz first showed up as an early proof of concept in the 29 June recap, described there as roughly a call graph with the async colouring overlaid, plus the escape edges from the closure analysis, plus the class-hierarchy edges that autoloading walked. That POC has now grown into a real module with a CLI entry point, and it is what this post covers: what shipped, why a graph beats a text report for this particular job, and what is still open.
What shipped
pext-viz went from a standalone POC to a module with a proper CLI entry point. It runs after a conversion done with --closed-world --async-coloring, and it reads the same intermediate analysis artifacts the transpiler already writes out during that pipeline rather than re-deriving anything itself. That matters: the call graph, the colouring, and the escape edges are computed once, by the pipeline covered in the async/await SAPI design notes, and pext-viz is a consumer of that output, not a second analysis pass.
The output is an interactive graph view. Nodes are functions and methods, edges are calls between them, and the async colouring from the closed-world pass is shown directly on the node as a color and border state rather than as a separate label to cross-reference. Escape edges and class-hierarchy edges are there too, behind a separate overlay toggle, so the default view stays readable as a call graph and the extra layers are opt-in when you need them.
Why a picture instead of a text report
Two use cases drove this. The first is deciding migration order on a closed-world conversion. An architect looking at which subsystem to move first wants the shape of the call graph in front of them, not a flat list of functions and their colours. A graph makes it obvious at a glance which subsystems are call-graph-isolated and can move independently, versus which ones are tangled into the rest of the codebase and will drag dependencies along with them.
The second is understanding why a specific handler got coloured async in the first place. The colouring pass is a worklist propagation through the reverse call graph, and the chain that justifies a given colour can run through several intermediate functions before it reaches an awaitable seed. Tracing that chain visually, by following coloured edges back from the handler to the I/O call that started it, is faster than grepping a text report for the same propagation path line by line.
What it's built on and what's next
For now pext-viz is an internal-facing tool. It is not yet a shipped npm package, and using it means running the CLI by hand after a closed-world conversion. The next step under consideration is publishing it alongside the Docusaurus audit report that pextc -r already generates, so a converted project's report includes a live control-flow view instead of requiring a separate CLI run to get the same information.
That decision is still open. It depends on how much of pext-viz's rendering can be pre-baked into a static report page versus how much benefits from staying interactive, and that tradeoff is being worked through before committing to a shape.