# How to Use NestJS Graph Inspector for Debugging: A Complete Guide

> Debug your NestJS app efficiently with the Graph Inspector. Visualize and export your dependency graph to find circular dependencies and understand module wiring.

- Repository: [nestjs/nest](https://github.com/nestjs/nest)
- Tags: how-to-guide
- Published: 2026-03-01

---

**The NestJS Graph Inspector lets you visualize and export your application's internal dependency graph at runtime, making it easy to detect circular dependencies and understand how providers and modules are wired together.**

The **Graph Inspector** is a built-in diagnostic tool in the `nestjs/nest` framework that records nodes (modules, providers, controllers) and edges (imports, exports, injections) as your application boots. This guide explains how to enable it, retrieve the graph data, and leverage it for debugging complex dependency hierarchies.

## Enabling the Graph Inspector

By default, the Graph Inspector is disabled in production to eliminate overhead. You can activate it either via environment variable or programmatically.

### Method 1: Environment Variable

Set the `INSPECTOR` environment variable to `"graph"` before starting your application:

```bash

# .env

INSPECTOR=graph

```

Nest will automatically instantiate the `GraphInspector` class from [`packages/core/inspector/graph-inspector.ts`](https://github.com/nestjs/nest/blob/main/packages/core/inspector/graph-inspector.ts) during bootstrap.

### Method 2: Programmatic Registration

For explicit control, pass a `GraphInspector` instance to the `inspect` option in `NestFactory.create`:

```typescript
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { GraphInspector } from '@nestjs/core/inspector/graph-inspector';

async function bootstrap() {
  const app = await NestFactory.create(AppModule, {
    logger: ['error', 'warn', 'log', 'debug', 'verbose'],
    inspect: new GraphInspector(),
  });

  await app.listen(3000);
}
bootstrap();

```

When disabled, Nest falls back to the **NoopGraphInspector** located in [`packages/core/inspector/noop-graph-inspector.ts`](https://github.com/nestjs/nest/blob/main/packages/core/inspector/noop-graph-inspector.ts), which implements the same interface but performs no operations, ensuring zero performance impact.

## Retrieving and Visualizing the Dependency Graph

Once enabled, inject the inspector using the **`APP_INSPECTOR`** token to access the graph data structure.

### Accessing via Controller Endpoint

Create a debug endpoint that exports the graph as JSON:

```typescript
import { Controller, Get, Inject } from '@nestjs/common';
import { GraphInspector } from '@nestjs/core/inspector/graph-inspector';
import { APP_INSPECTOR } from '@nestjs/core';

@Controller('debug')
export class GraphController {
  constructor(
    @Inject(APP_INSPECTOR) private readonly inspector: GraphInspector,
  ) {}

  @Get('graph')
  getGraph() {
    return this.inspector.getGraph();
  }
}

```

Visiting `GET /debug/graph` returns a JSON adjacency list:

```json
{
  "nodes": [
    { "id": "AppModule", "type": "module" },
    { "id": "UsersService", "type": "provider" }
  ],
  "edges": [
    { "from": "AppModule", "to": "UsersModule", "type": "import" },
    { "from": "UsersService", "to": "DatabaseService", "type": "inject" }
  ]
}

```

Pipe this output into visualization tools like **Graphviz**, **D3.js**, or **Mermaid** to generate interactive diagrams of your dependency hierarchy.

## Advanced Use Cases

### Detecting Circular Dependencies

The graph structure makes back-edges visible. Use a depth-first search (DFS) algorithm to programmatically detect cycles:

```typescript
import { Injectable, Inject } from '@nestjs/common';
import { GraphInspector } from '@nestjs/core/inspector/graph-inspector';
import { APP_INSPECTOR } from '@nestjs/core';

@Injectable()
export class CircleDetectorService {
  constructor(@Inject(APP_INSPECTOR) private readonly inspector: GraphInspector) {}

  findCycles(): string[][] {
    const graph = this.inspector.getGraph();
    const visited = new Set<string>();
    const stack: string[] = [];
    const cycles: string[][] = [];

    const dfs = (node: string) => {
      if (stack.includes(node)) {
        const startIdx = stack.indexOf(node);
        cycles.push(stack.slice(startIdx).concat(node));
        return;
      }
      if (visited.has(node)) return;
      visited.add(node);
      stack.push(node);
      const outgoing = graph.edges.filter(e => e.from === node);
      for (const edge of outgoing) dfs(edge.to);
      stack.pop();
    };

    for (const n of graph.nodes.map(n => n.id)) dfs(n);
    return cycles;
  }
}

```

### Exporting to Mermaid Format

Convert the graph to Mermaid syntax for documentation:

```typescript
import { Injectable, Inject } from '@nestjs/common';
import { GraphInspector } from '@nestjs/core/inspector/graph-inspector';
import { APP_INSPECTOR } from '@nestjs/core';

@Injectable()
export class MermaidGraphService {
  constructor(@Inject(APP_INSPECTOR) private readonly inspector: GraphInspector) {}

  toMermaid(): string {
    const graph = this.inspector.getGraph();
    const lines = ['graph TD'];
    for (const edge of graph.edges) {
      lines.push(`  ${edge.from} --> ${edge.to}`);
    }
    return lines.join('\n');
  }
}

```

### Testing with GraphInspector

In integration tests, retrieve the inspector from the module reference to verify your dependency structure:

```typescript
import { Test } from '@nestjs/testing';
import { AppModule } from '../src/app.module';
import { GraphInspector } from '@nestjs/core/inspector/graph-inspector';
import { APP_INSPECTOR } from '@nestjs/core';

describe('GraphInspector', () => {
  let inspector: GraphInspector;

  beforeAll(async () => {
    const moduleRef = await Test.createTestingModule({
      imports: [AppModule],
    }).compile();

    inspector = moduleRef.get(APP_INSPECTOR);
  });

  it('should contain expected nodes', () => {
    const graph = inspector.getGraph();
    expect(graph.nodes.map(n => n.id)).toContain('UsersService');
  });
});

```

The expected behavior is verified in the framework's own test suites: [`packages/core/test/inspector/graph-inspector.spec.ts`](https://github.com/nestjs/nest/blob/main/packages/core/test/inspector/graph-inspector.spec.ts) for unit tests and [`integration/inspector/e2e/graph-inspector.spec.ts`](https://github.com/nestjs/nest/blob/main/integration/inspector/e2e/graph-inspector.spec.ts) for end-to-end scenarios.

## Internal Architecture

According to the `nestjs/nest` source code, the Graph Inspector implements the `Inspector` contract used by Nest's internal diagnostics subsystem.

- **Core Implementation**: [`packages/core/inspector/graph-inspector.ts`](https://github.com/nestjs/nest/blob/main/packages/core/inspector/graph-inspector.ts) defines the `GraphInspector` class that records module-to-module relationships and provider injections during the instantiation phase.
- **Data Structure**: The inspector maintains a simple adjacency list of nodes and edges that can be serialized to JSON.
- **Token Registration**: The inspector is registered via the **`APP_INSPECTOR`** token, allowing you to substitute a custom implementation if needed.

## Summary

- The Graph Inspector is disabled by default; enable it via the `INSPECTOR=graph` environment variable or pass `inspect: new GraphInspector()` to `NestFactory.create`.
- Inject the inspector using the `APP_INSPECTOR` token to retrieve the dependency graph via `getGraph()`.
- The graph returns nodes (modules, providers, controllers) and edges (imports, exports, injections) as a JSON adjacency list.
- Use the graph to detect circular dependencies, visualize architecture with Mermaid/Graphviz, or verify dependency structure in tests.
- In production, Nest automatically uses `NoopGraphInspector` from [`packages/core/inspector/noop-graph-inspector.ts`](https://github.com/nestjs/nest/blob/main/packages/core/inspector/noop-graph-inspector.ts) to ensure zero overhead.

## Frequently Asked Questions

### How do I enable Graph Inspector in production environments?

You should not enable the Graph Inspector in production. When the `INSPECTOR` environment variable is unset or empty, Nest automatically substitutes the `NoopGraphInspector` class, which implements the same interface but performs no operations. This ensures your production builds incur no performance penalty from graph recording.

### What data format does Graph Inspector return?

The `getGraph()` method returns an object with two arrays: `nodes` (containing `id` and `type` fields) and `edges` (containing `from`, `to`, and `type` fields). This adjacency list format is compatible with standard graph visualization tools like Graphviz, D3.js, and Mermaid, and can be easily serialized to JSON for external analysis.

### Can I use Graph Inspector with @nestjs/testing?

Yes. When using `Test.createTestingModule()`, compile the module reference and retrieve the inspector via `moduleRef.get(APP_INSPECTOR)`. This allows you to verify that your testing module contains expected providers and that dependency relationships are wired correctly during automated testing.

### Does Graph Inspector impact application performance?

When enabled, the inspector adds minor overhead during the bootstrap phase as it records each module and provider instantiation. However, when disabled (the default), the framework uses `NoopGraphInspector` which contains empty methods, resulting in zero runtime impact. Only enable the inspector during development or debugging sessions.