Languages / TypeScript

TypeScript static analysis: unused exports, complexity and call graphs

To find unused exports and files in TypeScript, Knip is the standard single-ecosystem tool. repowise reaches the same kind of findings from a full import and call graph: tsconfig paths, npm, yarn and pnpm workspaces and package.json exports are resolved, Next.js and NestJS entry points are known, and each finding carries a confidence from git history.

Last reviewed: November 2026

Full tier

What repowise detects in TypeScript

Checked against the engine source. Every row runs locally with zero LLM calls.

repowise capabilities for TypeScript
Files parsed.ts, .tsx, .mts, .cts
Import resolutionFull. tsconfig and jsconfig paths with baseUrl fallback, npm, yarn and pnpm workspaces, package.json exports (wildcards included), # subpath imports, export * barrels, React Native platform suffixes
Call graphResolved calls with confidence per edge, heritage and type references
Dead codeUnreachable files, unused exports, zombie workspace packages; deletion-ready flag on unused exports
Health markersComplexity, class metrics, Extract Method plans, assertion-free tests and mock saturation in Jest and Vitest suites
Performance markersI/O and Prisma queries in loops, serial await, JSON.parse in loops, spread in reduce, nested quadratic loops
Coverage reportslcov (Jest, Vitest, c8, nyc), Cobertura, Clover
Frameworks recognisedNext.js App Router and pages, NestJS modules, Express, Hono, Fastify, Koa, tRPC, Remix, Angular, test-runner setup files

Specific to this language

How TypeScript code is read

Monorepo resolution is the hard part

A TypeScript monorepo imports through aliases: tsconfig paths, workspace package names and package.json exports maps. repowise resolves all three, maps build output back to source, and follows export * barrels, so an export used only through a barrel in another package is still counted as used.

Next.js and NestJS files are entry points

App Router files (page, layout, route, middleware, template, error, loading, not-found) and pages-router routes are roots, so they are never reported as unreachable. NestJS @Module controllers, providers, imports and exports become edges, as do tRPC procedures and Hono, Fastify and Koa route handlers.

Dynamic loading is read, not ignored

import(), require(), require.context, import.meta.glob, React.lazy, next/dynamic, jest.mock and vi.mock mark nearby files as possibly loaded at runtime. Those files stay at the review tier, and deletion-ready is reserved for findings with no runtime-load signal.

Honest comparison

Native TypeScript tools, and when they are enough

Native TypeScript analysis tools
ToolWhat it covers
KnipUnused files, exports, types and dependencies, with plugins for many frameworks and an auto-fix mode. The strongest single-ecosystem choice.
tsc --noUnusedLocalsUnused locals and parameters inside a file. Says nothing about unused exports.
ts-pruneUnused exports only. Its README marks it as in maintenance mode and points to Knip.
ESLintno-unused-vars and the complexity rule, per file.
dependency-cruiser, madgeModule dependency graphs, cycle detection and import rules.

Where repowise adds value

  • A confidence on every finding from git history and runtime-load signals, plus a deletion-ready flag an agent can act on.
  • The same pass covers the Python, Go or Java services in the repository, in one graph.
  • Health, performance markers (Prisma queries in loops, serial await) and hotspots on the same files.
  • get_dead_code over MCP, so Claude Code, Cursor or Codex can ask for deletion-ready findings directly.

How to run it

Analyse a TypeScript repository

From the repository root. Agents get the same results through the get_dead_code, get_health and get_context MCP tools.

uv tool install repowise        # or: pipx install repowise
repowise init --yes --no-prose     # index the repo, no API key
repowise dead-code --min-confidence 0.7 --safe-only
repowise health --refactoring-targets
npx vitest run --coverage --coverage.reporter=lcov
repowise coverage add coverage/lcov.info
repowise serve                     # graph, health and dead code in a local dashboard

Questions

What people ask before they try it.

Is repowise a Knip alternative?

Knip is built for the TypeScript ecosystem and can fix what it finds. repowise adds to it when the repository mixes languages, when you want each finding ranked by git history and runtime-load risk, or when an agent needs the findings over MCP with a deletion-ready flag. Many teams run both.

Does it understand tsconfig paths and pnpm workspaces?

Yes. tsconfig and jsconfig paths aliases, baseUrl, npm, yarn and pnpm workspaces (pnpm-workspace.yaml), package.json exports maps including wildcards, and Node # subpath imports are all resolved before dead code runs.

Will it report my Next.js pages as unused?

No. App Router files and pages-router routes are framework entry points. They are roots of the graph, so the files they import are reachable too.

How do I see the call graph of a TypeScript project?

Run repowise init, then repowise serve to explore the dependency and call graph, communities and C4 views in the local dashboard. Agents get the same edges through get_context with include=["callers"].

Does repowise send my TypeScript code to an LLM?

No. Parsing, the call graph, dead code, health scores, performance markers and git history all run locally with zero LLM calls. repowise init --yes --no-prose needs no API key, and the analysis itself makes no network calls. Written documentation prose is the one opt-in step that uses a model, and it can run on a local Ollama model.

Index a TypeScript repository.

Public repositories are free on repowise.dev. The CLI is open source and runs on your machine with no API key.