Skip to content
| Marketplace
Sign in
Visual Studio Code>Visualization>ReactWireNew to Visual Studio Code? Get it now.
ReactWire

ReactWire

ReactWire

|
2 installs
| (0) | Free
See the wiring of your React app: where it mounts, which component renders which, and where a prop or context travels. Click any node to open it.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

ReactWire

See the wiring of a React app inside VS Code: where React is mounted, which component renders which, and where a prop or a context travels. Click any node to open the component.

ReactWire analyses the source statically with the TypeScript compiler (through ts-morph). No running app, no backend, nothing leaves your machine.

What you get

  • Component tree growing from the mount point (the createRoot(...).render(<App />) call), laid out in straight levels like a house of cards: each level is one centred row, every component sits at its distance from the mount, and children line up under their parent regardless of the folder they live in. Bottom-to-top by default; switch to top-down or left-to-right in the toolbar. Node size grows with the number of components underneath it.
  • Only components and render edges. Props and contexts are not drawn; they are the job of the search box.
  • Two searches: the first box finds components by name, the second every component that touches a prop, context or hook with that name. Matches light up in lilac, a colour that is never one of the tags, and everything else fades, edges included, until you select a match: then its edges light up and its parents and children get a dashed outline, so only the matched components and the edges between them stay visible. In the prop search the name carries a mark: (in) the component receives it (own prop, consumed context), (out) it passes it down (prop on a child, provided context), (in+out) both. The match is exact and case-insensitive; * is a wildcard (App*, *Provider, *price*) and the Aa button makes both case-sensitive. The chips in the details panel fill the prop search with one click.
  • Colour tags. Select components (shift-click adds to the selection) and pick one of five colours in the Colour row right under the name in the details panel, or press 1–5 (0 puts them back to blue). The node and its edges take that colour. The Colours tab of the side panel lists the default blue and the five colours, each with a name you can edit (pages, to refactor…) and its toggles: Show off draws its components disabled in grey, Only keeps just the pressed colours on screen (press several to combine, press again to release), Remove takes a colour off every component, back to blue. Focus shown colours keeps the components of the visible colours with their ancestors and descendants, like Focus does for a selection, and stays lit until you press it again. Tags are remembered per folder and survive a refresh: a tagged component that moved to another file keeps its colour as long as its name is unique.
  • Providers are dimmed by default. Components that provide a context or are named …Provider only carry data, so they start disabled; tick the Providers box to bring them back, drawn as green hexagons so they never pass for regular components. The details panel lists them apart from regular components, in green.
  • Your own base colours. react-wire.colors sets component, provider, root, selected and edge. Any CSS colour; an empty value keeps the theme colour. Changes apply to the open graph without re-analysing.
  • The viewport stays put. Muting, hiding or focusing never changes your zoom; the selected component (or the mount point) keeps its place on screen. Fit re-centres on demand.
  • Details panel for the selected node: props received and props passed down, contexts (with the hook that reads them), who renders it, what it renders, with providers listed apart. Every name is a link that selects that node. Select several nodes (shift-click) and the panel shows one tab per node. Drag the left edge of the side panel to resize it; the width is remembered.
  • Unconnected toggle to include components that no path from the mount point reaches (rendered through a variable, compound components, dead code…). They stay out of the way otherwise.
  • Double-click a node or click its path to open the file at the declaration line.
  • Every on/off setting is a toggle button that stays lit while active. Parents and Children, both on by default, decide which side of the selection is highlighted: turn one off to see only who renders the selected component, or only what it renders, when the arrows alone do not make the direction obvious. Whole chain follows those parents all the way up to the mount point and those children all the way down to the leaves, instead of the direct ones only. Focus hides everything that is not highlighted and stays lit until you press it again. Fit re-centres, Refresh re-analyses. Shift-click, or cmd-click on a Mac, adds a component to the selection and removes it again.
  • Routes. When a component is declared in a router table (element: <Page /> or a lazy route), the path it is mounted on, nested paths included, shows in the details panel as a purple chip: a Routes section on the component itself, and next to each child in Renders that is reached through a route. The AI guide carries the same information.

Usage

  1. Open a React project (a folder with a tsconfig.json, or set react-wire.sourceGlobs).
  2. Click the ReactWire icon in the activity bar. The Analysis view shows which folder and branch are analysed and a summary of the result. By default it is the workspace folder, exactly as it sits on disk (checked-out branch, uncommitted changes included).
  3. To analyse a worktree or any other checkout, use Open Folder… in the view title (or click the folder entry). The choice is remembered for this workspace; open the workspace folder again to go back to the default.
  4. Open Graph in the view title, the summary entry, or ReactWire: Open Graph from the command palette, opens the interactive graph. Refresh re-analyses.
  5. The last entry is the config. By default there is none and the state lives only in VS Code. Click it to create one: a JSON file under .react-wire/ in the analysed folder holding your layers and the diagram they draw on. A layer is the whole state of the graph, the colours assigned and their names, both searches, the selected components, the focus, the direction and the toggles, so it can be committed, shared, and reopened exactly where you left it. With a config active, a Save button appears in the view title and the entry says when there are unsaved changes. Everything about configs starts from that entry (or Open Config… in the … menu): open one of the project's configs, create a new one, import a config file from anywhere, or go back to no config. Save Config As… in the same menu writes the current state wherever you choose. Both dialogs open in ~/.react-wire/, a folder in your home shared by every project, and remember the last folder you used. Ids in these files are relative to the analysed folder, so a config committed by a teammate works on your machine. The folder is watched: a config written by hand, by git or by an AI shows up in the list, and the active one reloads on its own.
  6. The Layers group in the graph toolbar moves between Code and the layers of the config, names them, adds an empty one, duplicates the current one or removes it. Code is always first and is the diagram itself, without colours: the first colour, name or Show you change while on Code creates a new layer at the end and moves you there. Searching, changing the direction, selecting or focusing on Code does not create anything.

Layers and the stored diagram

A config saves the diagram as it was analysed: components, who renders whom, mount points and providers. Nothing else, so it stays small and does not change every time a prop moves. Opening a config draws that diagram even if the checked-out branch no longer matches it: components that exist in the code get their props, contexts and location from the live analysis, and the rest are drawn with a dotted border and a not in code badge. Refresh replaces the stored diagram with the analysed code, and Save writes it back. With no config there is nothing stored and the graph always shows the analysed code.

A layer can also draw planned components that do not exist yet (dashed border, planned badge), regular or providers, with the edges to the real or planned components around them. There is no button for that: it is meant for an AI assistant explaining a refactor step by step, one layer per step, with colours for what goes away (a colour with Show off) and what appears. Since the stored diagram is in the file, an assistant can also compare it with the code after a pull and write a layer with what changed.

Working with an AI assistant

Write AI Guide in the … menu of the view asks for a folder, ~/.react-wire/ by default, and writes two files there: <project>-config.json, a real export of the current layers without the stored diagram, and <project>-AI-GUIDE.md, a short guide for the assistant: where that example lives, the format of a config, layers and planned components, how component ids are built, which colours exist and where to write the result so the extension picks it up. Then ask, for instance, Claude Code: "read ~/.react-wire/zenit-AI-GUIDE.md and write a config marking in red every component that touches the price prop and in green the pages that render them", or "…and explain in layers how you would split the checkout: what you would delete, what you would create". The file appears in Open Config…, and if it is the active one the graph reloads by itself.

A layer only stores what you decided: colours, names, searches, selection, focus and view options, plus the planned components it draws. It never stores positions, because the layout is computed from the graph and comes out the same every time. The diagram is written by the extension alone, and an assistant only reads it to compare, so writing a config costs a few hundred tokens per layer.

Settings:

Setting Default Purpose
react-wire.ignoreGlobs tests, specs, stories, __tests__, __mocks__, .storybook, e2e Files left out of the analysis. Bare names match anywhere
react-wire.colors {} (theme colours, important in red) Colour per kind of node and edge, see above
react-wire.tsconfigPath "" (auto-detect at the root) tsconfig used to load the project, relative to the root
react-wire.sourceGlobs ["src/**/*.{ts,tsx,js,jsx}"] Files analysed when no tsconfig is found

Changing any setting re-runs the analysis.

What it understands

  • Function components: declarations, arrow functions, memo, forwardRef, observer wrappers, default exports, export default Name, and const Fast = memo(Slow) aliases.
  • Props passed as JSX attributes and spreads. Forwarding is detected for destructured props, a props bag and a ...rest spread.
  • createContext declarations, <Ctx.Provider> and React 19 <Ctx> providers, useContext(Ctx), use(Ctx) and hooks that call them one level down.
  • Mount points: createRoot(el).render(...), a root kept in a variable, hydrateRoot, legacy ReactDOM.render / render / hydrate from react-dom. Wrappers in the mount JSX (<Providers><App /></Providers>) become the first levels of the tree.
  • JSX built outside components: route builders and similar helpers (buildRouter, a lazyMap object with dynamic imports) are credited to the components that use them, transitively.
  • React.lazy(() => import('./Page')), with or without .then(m => ({ default: m.Page })), and dynamic imports of components written directly in a component or route helper.
  • Dynamic imports with a computed path (import(`./${version}/index.ts`)): every module whose path fits the template counts as rendered, so all the variants hang from the component that picks one of them.
  • Compound components: <Card.Header /> resolves through Card.Header = HeaderSlot, a property in an object ({ Header: HeaderSlot }) or a shorthand.
  • Components picked at runtime: const Tag = variants[kind], cond ? A : B, custom ?? Default and React.lazy variables all resolve to every component they can be, so the graph connects to all the alternatives.
  • Route tables reached through helpers that build nothing themselves: RouterProvider fed by router = createBrowserRouter(routes) or by a hook called with { routes } still leads to the pages, including lazy routes that destructure the import (const { Page } = await import(…)).
  • Imports resolved by TypeScript, so paths aliases, package.json imports (#app/*), barrels and re-exports work.

Not covered yet: class components, hooks nested more than one level, and anything outside React (API calls, events, cookies).

Development

npm install
npm run verify      # typecheck + tests + build
npm run watch       # rebuild on change

Press F5 in VS Code to launch an Extension Development Host with the extension loaded.

Installing in your own VS Code

npm run install:local   # verify, package react-wire-<version>.vsix and install it

npm run package only builds the .vsix; install it by hand with code --install-extension react-wire-<version>.vsix --force, or through Extensions → … → Install from VSIX. Reinstall after each change; bump version in package.json so VS Code picks up the new build.

Layout:

src/core        pure analysis: ts-morph project → WireGraph (no VS Code, fully unit-tested)
src/extension   VS Code glue: analysis view, folder choice, commands, settings, shared analysis service, webview panel
src/webview     the graph UI: Cytoscape rendering, filters, details panel
src/shared      the message protocol between extension and webview

The core is the only place that reasons about code. The extension never inspects source files and the webview never knows where the graph came from.

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
  • Your Privacy Choices
  • Consumer Health Privacy
© 2026 Microsoft