or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

cli-tools.mdconfiguration-management.mdcore-analysis.mdindex.mdoutput-formatting.mdreporter-plugins.mdrule-system.mdtranspiler-support.md
tile.json

reporter-plugins.mddocs/

Reporter Plugins

Built-in reporter plugins for generating statistics and custom output formats.

Capabilities

Sample Statistics Reporter Plugin

Generate detailed statistics about module dependencies and project structure.

/**
 * Sample statistics reporter plugin that analyzes dependency patterns
 * @param cruiseResult - Analysis result from cruise function
 * @returns Reporter output with dependency statistics in JSON format
 */
import statsPlugin from "dependency-cruiser/sample-reporter-plugin";

type StatsReporterPlugin = (cruiseResult: ICruiseResult) => IReporterOutput;

Usage Examples:

import { cruise, format } from "dependency-cruiser";
import statsPlugin from "dependency-cruiser/sample-reporter-plugin";

// Get analysis results
const cruiseResult = await cruise(["src"]);

// Generate statistics using plugin directly
const stats = statsPlugin(cruiseResult.output);
console.log(JSON.parse(stats.output));

// Or use via format function
const statsReport = await format(cruiseResult.output, {
  outputType: "plugin:stats-reporter-plugin.js"
});

Statistics Generated:

{
  "moduleCount": 150,
  "dependencyCount": 423,
  "minDependenciesPerModule": 0,
  "maxDependenciesPerModule": 15,
  "meanDependenciesPerModule": 2.82,
  "medianDependenciesPerModule": 2,
  "p75DependenciesPerModule": 4,
  "minDependentsPerModule": 0,
  "maxDependentsPerModule": 8,
  "meanDependentsPerModule": 2.82,
  "medianDependentsPerModule": 2,
  "p75DependentsPerModule": 4
}

Mermaid Reporter Plugin

Generate Mermaid diagrams for dependency visualization.

/**
 * Mermaid reporter plugin that creates flowchart diagrams
 * @param cruiseResult - Analysis result from cruise function
 * @returns Reporter output with Mermaid diagram syntax
 */
import mermaidPlugin from "dependency-cruiser/mermaid-reporter-plugin";

type MermaidReporterPlugin = (cruiseResult: ICruiseResult) => IReporterOutput;

Usage Examples:

import { cruise, format } from "dependency-cruiser";

// Generate Mermaid diagram via format
const mermaidDiagram = await format(cruiseResult.output, {
  outputType: "mermaid",
  collapse: 2,
  includeOnly: "^src/"
});

// Write to file for use in documentation
import fs from "fs/promises";
await fs.writeFile("dependency-graph.md", `
# Dependency Graph

\`\`\`mermaid
${mermaidDiagram.output}
\`\`\`
`);

// Or use plugin directly
import mermaidPlugin from "dependency-cruiser/mermaid-reporter-plugin";
const diagram = mermaidPlugin(cruiseResult.output);

3D Visualization Reporter Plugin

Generate 3D visualization data for dependency graphs.

/**
 * 3D visualization reporter plugin
 * @param cruiseResult - Analysis result from cruise function  
 * @returns Reporter output with 3D visualization data
 */
import threeDPlugin from "dependency-cruiser/sample-3d-reporter-plugin";

type ThreeDReporterPlugin = (cruiseResult: ICruiseResult) => IReporterOutput;

Usage Examples:

import threeDPlugin from "dependency-cruiser/sample-3d-reporter-plugin";

// Generate 3D visualization data
const threeDData = threeDPlugin(cruiseResult.output);

// Use with 3D visualization libraries
const visualizationData = JSON.parse(threeDData.output);
// Process with Three.js, D3.js, or other 3D libraries

Custom Reporter Plugin Development

Create custom reporter plugins for specialized output formats.

/**
 * Reporter plugin function signature
 * @param cruiseResult - Complete analysis results
 * @returns Object with output string and exit code
 */
type ReporterPlugin = (cruiseResult: ICruiseResult) => IReporterOutput;

interface IReporterOutput {
  /** Generated output (usually string, but can be structured data) */
  output: string | ICruiseResult;
  
  /** Exit code - 0 for success, non-zero for errors/violations found */
  exitCode: number;
}

Custom Plugin Example:

// custom-csv-reporter.js
function customCsvReporter(cruiseResult) {
  const headers = ["source", "target", "circular", "dynamic", "dependencyTypes"];
  const rows = [headers.join(",")];
  
  cruiseResult.modules.forEach(module => {
    module.dependencies.forEach(dep => {
      const row = [
        module.source,
        dep.resolved,
        dep.circular,
        dep.dynamic,
        dep.dependencyTypes.join(";")
      ];
      rows.push(row.join(","));
    });
  });
  
  return {
    output: rows.join("\n"),
    exitCode: cruiseResult.summary.error > 0 ? 1 : 0
  };
}

export default customCsvReporter;

Using Custom Plugin:

import { format } from "dependency-cruiser";
import customCsvReporter from "./custom-csv-reporter.js";

// Use plugin directly
const csvReport = customCsvReporter(cruiseResult.output);

// Or register and use via format
const csvReport = await format(cruiseResult.output, {
  outputType: "plugin:./custom-csv-reporter.js"
});

Plugin Integration Patterns

Common patterns for integrating reporter plugins into workflows.

Build Process Integration:

// build-integration.js
import { cruise } from "dependency-cruiser";
import statsPlugin from "dependency-cruiser/sample-reporter-plugin";

async function generateBuildMetrics() {
  const result = await cruise(["src"]);
  
  // Generate statistics
  const stats = statsPlugin(result.output);
  const metrics = JSON.parse(stats.output);
  
  // Fail build if metrics exceed thresholds
  if (metrics.maxDependenciesPerModule > 10) {
    console.error("Module complexity too high!");
    process.exit(1);
  }
  
  // Save metrics for tracking
  await fs.writeFile(
    "build-metrics.json", 
    JSON.stringify({
      timestamp: new Date().toISOString(),
      ...metrics
    }, null, 2)
  );
}

Documentation Generation:

// doc-generation.js
async function generateDocumentation() {
  const result = await cruise(["src"]);
  
  // Generate multiple formats
  const [htmlReport, mermaidDiagram, stats] = await Promise.all([
    format(result.output, { outputType: "html" }),
    format(result.output, { outputType: "mermaid", collapse: 2 }),
    format(result.output, { outputType: "plugin:stats-reporter-plugin.js" })
  ]);
  
  // Write documentation files
  await Promise.all([
    fs.writeFile("docs/dependency-report.html", htmlReport.output),
    fs.writeFile("docs/architecture.md", `
# Architecture Overview

## Dependency Graph

\`\`\`mermaid
${mermaidDiagram.output}
\`\`\`

## Statistics

${JSON.stringify(JSON.parse(stats.output), null, 2)}
    `),
  ]);
}

Plugin Configuration and Options

Configure plugin behavior through cruise and format options.

Mermaid Plugin Configuration:

// Mermaid with custom styling and filtering
const mermaidOutput = await format(result.output, {
  outputType: "mermaid",
  
  // Focus on specific areas
  focus: "src/core",
  
  // Collapse for better overview
  collapse: "^src/[^/]+/",
  
  // Exclude test files
  exclude: ["test/", "*.test.js"],
  
  // Only show local dependencies
  includeOnly: { dependencyTypes: ["local"] }
});

Statistics Plugin with Filtering:

// Get statistics for specific subset
const filteredResult = {
  ...cruiseResult.output,
  modules: cruiseResult.output.modules.filter(
    module => module.source.startsWith("src/core")
  )
};

const coreStats = statsPlugin(filteredResult);

Error Handling in Plugins

Proper error handling and exit code management in reporter plugins.

Plugin with Error Handling:

function robustReporter(cruiseResult) {
  try {
    // Plugin logic here
    const output = generateReport(cruiseResult);
    
    // Determine exit code based on violations
    const hasErrors = cruiseResult.summary.error > 0;
    const hasWarnings = cruiseResult.summary.warn > 0;
    
    return {
      output,
      exitCode: hasErrors ? 2 : hasWarnings ? 1 : 0
    };
    
  } catch (error) {
    return {
      output: `Error in reporter plugin: ${error.message}`,
      exitCode: 3
    };
  }
}

Performance Considerations

Optimize plugin performance for large codebases.

Efficient Plugin Implementation:

function efficientStatsPlugin(cruiseResult) {
  // Use single pass for multiple calculations
  let totalDeps = 0;
  let maxDeps = 0;
  let minDeps = Infinity;
  const depCounts = [];
  
  cruiseResult.modules.forEach(module => {
    const depCount = module.dependencies.length;
    totalDeps += depCount;
    maxDeps = Math.max(maxDeps, depCount);
    minDeps = Math.min(minDeps, depCount);
    depCounts.push(depCount);
  });
  
  // Sort once for percentile calculations
  depCounts.sort((a, b) => a - b);
  
  const moduleCount = cruiseResult.modules.length;
  const medianIndex = Math.floor(moduleCount * 0.5);
  const p75Index = Math.floor(moduleCount * 0.75);
  
  return {
    output: JSON.stringify({
      moduleCount,
      dependencyCount: totalDeps,
      minDependenciesPerModule: minDeps === Infinity ? 0 : minDeps,
      maxDependenciesPerModule: maxDeps,
      meanDependenciesPerModule: totalDeps / moduleCount,
      medianDependenciesPerModule: depCounts[medianIndex] || 0,
      p75DependenciesPerModule: depCounts[p75Index] || 0
    }, null, 2),
    exitCode: 0
  };
}

Plugin Testing

Test reporter plugins to ensure correct behavior.

Plugin Test Example:

// test-plugin.js
import assert from "assert";
import statsPlugin from "dependency-cruiser/sample-reporter-plugin";

function testStatsPlugin() {
  const mockCruiseResult = {
    modules: [
      { source: "a.js", dependencies: [{}, {}] },
      { source: "b.js", dependencies: [{}] },
      { source: "c.js", dependencies: [] }
    ],
    summary: { totalCruised: 3, totalDependenciesCruised: 3 }
  };
  
  const result = statsPlugin(mockCruiseResult);
  const stats = JSON.parse(result.output);
  
  assert.equal(stats.moduleCount, 3);
  assert.equal(stats.dependencyCount, 3);
  assert.equal(stats.maxDependenciesPerModule, 2);
  assert.equal(stats.minDependenciesPerModule, 0);
  
  console.log("Stats plugin test passed");
}

testStatsPlugin();