Supported language

TypeScript

Analyze TypeScript projects by generating a dependency graph and optional complexity file with your own toolchain, then load coverage manually when you need it.

AtlasArc can analyze TypeScript projects when your project exports the structure that AtlasArc needs to read. TypeScript analysis is artifact-backed: dependency-cruiser supplies the required graph, while compatible SARIF and LCOV can add metrics. Your repository keeps control of the Node version, package manager, TypeScript compiler, framework plugins, and test runner. AtlasArc does not install packages or run npm for you.

The usual flow is:

dependency graph JSON
+ optional ESLint/SonarJS SARIF
-> AtlasArc
-> source-folder graph, metrics, reports, and exports

LCOV coverage
-> selected manually in AtlasArc after the graph is loaded

What AtlasArc understands

AtlasArc understands TypeScript as a graph of source files and folders. It reads the files your project imports, re-exports, loads dynamically, or references as types, then rolls those file-level relationships up into source-folder architecture units.

At the architecture level, TypeScript provides:

  • source-folder dependency graph;
  • per-folder file internals in the Topology Graph: open a source folder to inspect its files and any import tangles inside it;
  • the same source-folder evidence in Topology, Matrix, Composition, Subsystems, and Hotspots when the chosen view's required metrics are available.

The current TypeScript metric-family contract is complete below. The Metrics Matrix explains the metrics and their product-wide uses; this table owns the backend availability states.

Metric family TypeScript state Evidence
Fan-in, fan-out, dependency references Supported Supplied dependency graph
Instability Supported Supplied dependency graph
Abstractness Unsupported JVM class/type evidence only
Distance from the main sequence Unsupported Requires Abstractness
Relative visibility Unsupported JVM visibility evidence only
Cyclomatic complexity maximum/average Optional evidence ESLint/SonarJS SARIF
Cognitive complexity maximum/average Optional evidence ESLint/SonarJS SARIF
Source-file count Supported TypeScript artifact model
Lines of code Supported TypeScript artifact model
Method count Unsupported JVM method evidence only
Line coverage Optional evidence Manually loaded LCOV
Branch coverage Optional evidence Manually loaded LCOV with branch records
Cycle status Supported Supplied dependency graph
Cycle-group count and largest cycle size Supported Supplied dependency graph
Source-folder architecture-unit count Supported TypeScript artifact model
Internal edges, boundary fan-in, boundary fan-out Supported Supplied dependency graph
Subsystem instability and cohesion Supported Supplied dependency graph
Recursive abstractness and recursive visibility Unsupported JVM public-surface evidence only
CCD, ACD, RACD, and NCCD dependency shape Supported Supplied dependency graph
ARV and GRV project visibility Unsupported JVM visibility evidence only

TypeScript does not provide class/member-level dependency examples or source write-back for accepted dependencies. Missing optional data is shown as unavailable, not as zero. For example, if you load LCOV with line coverage but no branch records, line coverage can be shown while branch coverage stays unavailable.

Construct support

AtlasArc does not parse TypeScript syntax to discover architecture dependencies. It reads the resolved project-local file edges in the graph your project supplies, then rolls those edges up into source-folder architecture units. The graph generator decides which source constructs and aliases it can resolve; AtlasArc keeps the resulting file relationship and its available dependency kind.

The generated graph usually comes from the open source sverweij/dependency-cruiser project. In a supplied graph, AtlasArc handles these common relationship categories:

Relationship present in the graph AtlasArc treatment
Static imports, re-exports, and barrel edges Project-local resolved files become source-folder dependency edges.
Dynamic imports Resolved file edges remain source coupling; AtlasArc does not infer route or framework semantics.
CommonJS require Included when the supplied graph resolves it to selected project source.
Type-only imports, exports, and import-type references Included as source coupling when emitted, even though TypeScript may erase them at runtime.
JSDoc import references Included when graph generation is configured to emit and resolve them.
Configured path or workspace aliases Included when the supplied graph resolves the alias to selected project source. AtlasArc does not resolve aliases independently.
External packages and Node built-ins Excluded from the project source-folder architecture.
Unresolved imports Reported as artifact-quality evidence rather than guessed into the graph.

Some TypeScript constructs matter to a reader, but AtlasArc recognizes them only as the imports or references they express:

Construct What AtlasArc can say
extends and implements The imported base or interface file is a dependency.
Generic constraints and type aliases The imported type source is a dependency.
Decorators The decorator module is a dependency.
Function and constructor calls The imported module is a dependency; member-level call evidence is not available.
Angular, React, NestJS, or similar framework imports Imported source files are dependencies; framework runtime behavior is not inferred.

Known boundaries

AtlasArc does not infer TypeScript dependencies from:

  • Angular templates, Vue/Svelte component internals, or framework metadata that does not appear as a resolved source-file dependency;
  • dependency injection container wiring, route strings, REST URLs, GraphQL endpoint strings, or plugin registry keys;
  • generated clients, declaration files, mocks, stories, fixtures, or test sources unless your dependency graph intentionally includes them;
  • external npm packages and Node built-ins as source folders;
  • unresolved imports.

In a mixed Java/Kotlin and TypeScript repository, analyze server-side JVM code and TypeScript frontends as separate sources. Java and Kotlin can share one JVM graph when they compile together. TypeScript projects load from their generated files. Cross-language API contracts such as REST routes, GraphQL schemas, and generated clients are architectural agreements, but they are not ordinary Java method calls or TypeScript imports.

Files to generate

Create these files under the TypeScript project root you want to analyze:

File Required What it adds
.atlasarc/depgraph.json Yes Source-file dependencies from dependency-cruiser.
.atlasarc/eslint.sarif No Cyclomatic complexity and cognitive complexity, when exported by ESLint and SonarJS.

The dependency graph is required. SARIF enriches the graph with complexity metrics, but the project can still load without it.

Coverage is different. Do not place an LCOV file in .atlasarc expecting AtlasArc to find it. Run your tests normally, let your coverage tool produce LCOV wherever it normally does, then choose that file from the AtlasArc coverage action after the TypeScript graph is loaded.

In AtlasArc

  1. Generate `.atlasarc/depgraph.json` with your project toolchain.
  2. Rescan sources so AtlasArc sees the updated graph file.
  3. Select the TypeScript source from the analysis source picker.
  4. Load LCOV coverage manually when you want coverage overlays.

Generate the graph

Install dependency-cruiser in the TypeScript project and pin it with the rest of your dev dependencies:

npm install --save-dev dependency-cruiser

With pnpm:

pnpm add --save-dev dependency-cruiser

Create a dependency-cruiser config at the project root:

// .dependency-cruiser.cjs
module.exports = {
  // AtlasArc reads the module graph and runs its own cycle detection, so no `forbidden`
  // rules are needed here. Keep your team's own dependency-cruiser rules in a separate config.
  options: {
    tsConfig: { fileName: 'tsconfig.json' },
    exclude: { path: ['\\.spec\\.tsx?$', '\\.test\\.tsx?$', '/dist/', '/coverage/', '/node_modules/'] },
    doNotFollow: { path: 'node_modules' },
    combinedDependencies: true,
  },
};

Add scripts that write AtlasArc's default graph path:

{
  "scripts": {
    "atlasarc:prepare": "node -e \"require('fs').mkdirSync('.atlasarc', { recursive: true })\"",
    "atlasarc:deps": "depcruise \"src\" --include-only \"^src\" --output-type json > .atlasarc/depgraph.json"
  }
}

Run the graph script before loading or rescanning the TypeScript project in AtlasArc:

npm run atlasarc:prepare
npm run atlasarc:deps

Add complexity metrics

If you want cyclomatic and cognitive complexity, add ESLint, SonarJS, and the SARIF formatter:

npm install --save-dev eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-plugin-sonarjs @microsoft/eslint-formatter-sarif

With pnpm:

pnpm add --save-dev eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-plugin-sonarjs @microsoft/eslint-formatter-sarif

Use a dedicated ESLint config so your normal lint thresholds do not change:

// eslint-atlasarc.config.mjs
import tsParser from '@typescript-eslint/parser';
import tsPlugin from '@typescript-eslint/eslint-plugin';
import sonarjs from 'eslint-plugin-sonarjs';

export default [
  {
    ignores: ['dist/**', 'coverage/**', 'node_modules/**', '.atlasarc/**', '**/*.spec.*', '**/*.test.*'],
  },
  {
    files: ['src/**/*.{ts,tsx}'],
    languageOptions: {
      parser: tsParser,
      parserOptions: {
        project: './tsconfig.json',
        tsconfigRootDir: process.cwd(),
        ecmaVersion: 2020,
        sourceType: 'module',
      },
    },
    plugins: { '@typescript-eslint': tsPlugin, sonarjs },
    rules: {
      // Threshold 0 makes ESLint emit a finding for *every* function, so the SARIF carries a
      // score for each one. AtlasArc reads those scores; it does not treat them as violations.
      complexity: ['warn', 0],
      'sonarjs/cognitive-complexity': ['warn', 0],
    },
  },
];

Then add the SARIF export:

{
  "scripts": {
    "atlasarc:sarif": "eslint \"src/**/*.{ts,tsx}\" --config eslint-atlasarc.config.mjs --format @microsoft/eslint-formatter-sarif --output-file .atlasarc/eslint.sarif"
  }
}

Run it before rescanning when you want updated complexity metrics:

npm run atlasarc:sarif

Workspaces

For npm, pnpm, Angular, or Nx workspaces, choose the source root you want AtlasArc to analyze and generate one dependency graph for that root. Avoid one accidental all-repository graph unless the whole repository is genuinely the architecture unit you want to inspect.

Examples:

Project shape Dependency-cruiser input
Single app src
npm/pnpm workspace app apps/web/src
Angular CLI project projects/admin/src
Nx app apps/web/src
Nx library libs/design-system/src

Give each analyzed root its own .atlasarc/ directory. AtlasArc infers the project root from where .atlasarc/depgraph.json lives, so the graph for apps/web must sit at apps/web/.atlasarc/depgraph.json — not in a shared folder at the repo root. Example root-level scripts:

{
  "scripts": {
    "atlasarc:web:prepare": "node -e \"require('fs').mkdirSync('apps/web/.atlasarc', { recursive: true })\"",
    "atlasarc:web:deps": "depcruise \"apps/web/src\" --include-only \"^apps/web/src\" --output-type json > apps/web/.atlasarc/depgraph.json",
    "atlasarc:web:sarif": "eslint \"apps/web/src/**/*.{ts,tsx}\" --config eslint-atlasarc.config.mjs --format @microsoft/eslint-formatter-sarif --output-file apps/web/.atlasarc/eslint.sarif"
  }
}

For Angular or Nx, use the project sourceRoot as the dependency-cruiser input unless your team has a better source boundary.

Load coverage

TypeScript coverage uses LCOV. It is not tied to Babel; Vitest, Jest, nyc, c8, Playwright, Angular, and other tools can write LCOV.

Generate coverage with your normal test command. For example:

vitest run --coverage --coverage.reporter=lcov

After the TypeScript graph is loaded in AtlasArc, use the coverage action and select the generated lcov.info or .lcov file. AtlasArc does not auto-detect LCOV files and does not reload them on rescan; coverage is a manually loaded, session-scoped overlay.

The important part is path alignment. SF: entries in lcov.info should point at the same original TypeScript files that appear in depgraph.json. If coverage points at compiled JavaScript, generated files, or paths outside the selected source root, AtlasArc cannot attach coverage to the right source folders reliably.

Check before loading

Before loading or rescanning the TypeScript project, check:

  • .atlasarc/depgraph.json exists and contains a top-level modules array;
  • modules[].source paths point at original TypeScript files, not generated JavaScript;
  • imports through aliases are resolved the way your team expects;
  • optional SARIF paths match the same source files as dependency-cruiser;
  • monorepo apps and libraries are split into the analysis roots your team actually wants to review.

Before loading coverage, check:

  • the LCOV file exists where your coverage tool wrote it;
  • SF: paths point at original .ts or .tsx files;
  • the LCOV paths match the TypeScript graph that is currently loaded in AtlasArc;
  • branch records exist if you expect Branch Coverage to be available.

Missing SARIF does not block analysis. Missing LCOV does not affect source readiness. Missing or invalid dependency graph JSON does.