Express Map

Visual Route and Middleware Navigation for VS Code

Express Map is a free, open source Visual Studio Code extension that statically analyses Express.js applications and renders an interactive sidebar tree of every route, middleware layer, and template file. No running server is required. Open the project and the map appears.

The existing Express tooling ecosystem in VS Code has been largely stagnant since 2017. The available options are almost entirely snippet collections targeting Express 4, many of which have not been updated in seven or more years. The one meaningful exception is a route viewer that acknowledges a known prefix resolution bug in its own documentation and provides no middleware or template awareness. Express Map fills that gap with accurate static analysis, full prefix resolution at any depth, and a complete picture of how requests move through an Express application.

Features

  • Route Tree

    Every route in the project is displayed in a sidebar tree with its HTTP method, fully resolved path (including all app.use() prefix propagation at any depth), source file, and line number. Routes are expandable to show their middleware chain in order and the template they render. Clicking any route navigates directly to its definition. Routes are grouped by path prefix for readability.

  • Middleware Chain Visualization

    For each route, Express Map surfaces the complete ordered middleware stack: global middleware registered on app, router-level middleware registered on the router, and route-level middleware passed as handler arguments. Each middleware entry shows its name if it is a named function, or its file and line number if it is anonymous.

  • Template Navigation

    Routes that call res.render() are linked to the template they render. The template name appears as a child of the route in the tree and is clickable. A separate Templates group shows every template file with the routes that render it, enabling navigation from template to route or route to template. Hold Cmd (macOS) or Ctrl (Windows/Linux) and click a template name in source to open the template directly.

  • CodeLens

    Route metadata appears inline above each handler function in the editor:

    GET /admin/users · 2 middleware · renders admin/users

    Clicking the CodeLens label reveals that route in the Express Map panel. As the cursor moves through a route file, the corresponding route is highlighted in the tree automatically.

  • Broken Reference Detection

    Routes that call res.render() with a template name that does not exist in the views directory are flagged three ways: a red squiggle on the call site, an entry in the Problems panel, and a Broken References group in the tree.

  • Orphaned Template Detection

    Template files that exist in the views directory but are never referenced by any res.render() call are listed under an Orphaned Templates group. These are candidates for cleanup.

  • Duplicate Route Detection

    Multiple handlers registered for the same HTTP method and resolved path are grouped under a Duplicate Routes section with a warning indicator. Express silently uses the first match, so this detection surfaces conflicts that are otherwise invisible.

  • Async Safety Warnings

    Async route handlers with no try/catch block are flagged with a warning. In Express 4, unhandled promise rejections crash the server. In Express 5, the framework handles this natively, so warnings are automatically suppressed when Express 5 is detected.

  • Copilot Integration

    Express Map registers a GitHub Copilot language model tool that gives the AI a structured understanding of the full application including routes, templates, broken references, async issues, duplicates, and orphaned templates. The tool is privacy-first: it only runs when explicitly referenced in a Copilot Chat message and never sends data to the model automatically or in the background. Route paths, file structure, and template names stay local until explicitly shared. Source code content, environment variables, secrets, and runtime data are never sent.

  • Auto-Refresh

    A file system watcher monitors all .js, .ts, and .ejs files in the workspace. Any change triggers a debounced re-analysis at 500 ms so the tree stays current without manual refresh.

Supported Template Engines

EJS • Pug/Jade • Handlebars/HBS • Mustache • Nunjucks • Twig • Liquid • Eta

Template engine detection is automatic via app.set('view engine', ...) inspection, with a fallback to views directory scanning. No configuration is required.

Express Version Compatibility

Feature Express 4 Express 5
Route tree, CodeLens, template links Yes Yes
{:param} optional params (path-to-regexp v8) No Yes
{*name} named wildcards No Yes
Array mount paths app.use(['/a', '/b'], fn) No Yes
Async errors caught by framework No (warnings shown) Yes (warnings suppressed)

The detected Express version is shown in the status bar tooltip.

How It Works

Express Map uses Babel's AST parser to read source files without executing them. On activation it finds the entry point via the package.json main field or common filenames (app.js, server.js, index.js), follows require() and import statements to discover all router files, detects app.set('views', ...) and app.set('view engine', ...) calls, and records every route registration with its full prefix stack resolved at any depth.

Dynamic route paths using template literals are converted to parameterized equivalents where possible. Fully dynamic paths built from variables or computed expressions are represented as [varName] in the tree.

Known Limitations

  • Dynamic route paths: Template literals like `/${section}/page` are converted to /:section/page. Fully dynamic paths (variables, computed expressions) appear as [varName].
  • Dynamic render calls: res.render(view) where view is a variable cannot be statically resolved. The render reference is collected via object property scanning as a best-effort.
  • Re-exported routers: Routers exported through index files with re-exports may not always be followed.
  • Array-mounted sub-routers: app.use(['/a', '/b'], router) is analysed once per mount path for route listing, but because file analysis is deduplicated, only the first path is used when routes inside share the same file.
  • No runtime analysis: Middleware conditionally registered at runtime will not be detected.

Requirements

  • VS Code 1.118.0 or later
  • An Express.js project with a package.json in the workspace root
  • Entry point discovered via package.json "main" field, or one of: app.js, server.js, index.js
  • Express 4 or 5, both fully supported
  • No configuration needed

Installation

Search for Express Map in the VS Code Extensions panel, or install directly from the Marketplace. Source code is available on GitHub under the MIT license.

Related Extensions