Skip to content

AdametherzLab/ts-module-fixer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

1 Commit
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

CI TypeScript License: MIT

ts-module-fixer πŸ”§

Features

  • πŸ” Deep Trace Analysis - Parses tsc --traceResolution output to pinpoint failure points
  • 🩹 Smart Patching - Suggests precise paths, baseUrl, and rootDirs changes
  • 🏒 Monorepo Native - Understands npm/yarn/pnpm workspaces and Rush monorepos
  • πŸš€ Zero Config - Works out of the box with sensible defaults
  • πŸ”’ Safe by Default - Dry-run mode previews changes before writing

Installation

npm install @adametherzlab/ts-module-fixer
# or
bun add @adametherzlab/ts-module-fixer

CLI Usage

# Analyze and suggest fixes
npx ts-module-fixer --tsconfig ./tsconfig.json

# Preview changes without writing
npx ts-module-fixer --dry-run --verbose

# Save patched config to new file
npx ts-module-fixer --output tsconfig.fixed.json

# Full options
npx ts-module-fixer --tsconfig ./tsconfig.json --dry-run --verbose --output ./fixed.json

Flags:

  • --tsconfig <path> - Path to tsconfig.json (default: ./tsconfig.json)
  • --dry-run - Show proposed changes without writing files
  • --verbose - Display detailed resolution trace analysis
  • --output <path> - Write fixed config to specific file instead of in-place

Programmatic API

// REMOVED external import: import { diagnose, buildPatch, applyFix, type DiagnosisResult, type FixerOptions } from "@adametherzlab/ts-module-fixer";
import * as path from "path";

const options: FixerOptions = {
  projectRoot: path.join(process.cwd(), "my-project"),
  tsConfigPath: path.join(process.cwd(), "my-project", "tsconfig.json"),
  dryRun: false
};

// Run diagnosis on trace output
const traceOutput = await getTraceOutput(); // Your trace capture logic
const diagnosis: DiagnosisResult = diagnose(traceOutput, options);

// Build and apply patches
if (diagnosis.failingImports.length > 0) {
  const patch = buildPatch(diagnosis.failingImports, options);
  await applyFix(options.tsConfigPath, patch);
}

API Reference

main(argv?: readonly string[]): Promise<number>

CLI entry point. Returns exit code 0 (success), 1 (unresolvable), or 2 (usage error).

const exitCode = await main(["--tsconfig", "./tsconfig.json", "--dry-run"]);

parseTraceOutput(trace: string): ResolutionTrace

Parses raw tsc --traceResolution output into structured steps.

classifyFailingImport(step: ResolutionStep, context: ResolutionContext): RootCause

diagnose(trace: ResolutionTrace, options: FixerOptions): DiagnosisResult

buildPatch(imports: FailingImport[], options: FixerOptions): TsConfigPatch

applyFix(tsConfigPath: string, patch: TsConfigPatch): Promise<void>

Applies patch to tsconfig.json file on disk.

mergePatchIntoTsConfig(current: ParsedTsConfig, patch: TsConfigPatch): ParsedTsConfig

formatPatchAsSnippet(patch: TsConfigPatch): string

RootCause Reference

Cause Symptom Fix
PathMappingMissing Import like @org/package not found Adds paths entry mapping to actual location
IncorrectBaseUrl Relative imports resolve from wrong directory Updates baseUrl to project root or src
RootDirsMissing Virtual directory structure not recognized Configures rootDirs for composite projects
ExtensionResolutionFailed .js import not finding .ts file Ensures allowJs and proper paths
NodeModulesNotFound External package resolution fails Validates node_modules in rootDirs or suggests typeRoots

Before & After Example

Broken tsconfig.json:

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "NodeNext",
    "baseUrl": "."
  }
}

Import failing: import { utils } from "@myapp/shared";

Patch generated by ts-module-fixer:

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@myapp/*": ["packages/*/src"]
    }
  }
}

Monorepo & Workspaces

ts-module-fixer automatically detects workspace configurations:

// REMOVED external import: import { detectWorkspace, runFixer } from "@adametherzlab/ts-module-fixer";

const workspace = detectWorkspace("./monorepo-root"); // Detects npm/yarn/pnpm/rush
const result = await runFixer({
  projectRoot: "./monorepo-root",
  monorepoWorkspace: workspace
});

Supports:

  • npm workspaces - Reads workspaces from root package.json
  • yarn/pnpm - Parses pnpm-workspace.yaml and yarnrc
  • Rush - Understands rush.json configuration

Troubleshooting FAQ

Q: "Error: tsc not found on PATH" A: Ensure TypeScript is installed globally (npm install -g typescript) or locally in your project. The tool requires tsc to generate resolution traces.

Q: "Failed to parse tsconfig.json" A: Your tsconfig might use JSON5 syntax (comments, trailing commas). ts-module-fixer uses a lenient JSON5 parser internally, but if you see this error, ensure your file is valid JSON5 or run it through json5 -c tsconfig.json first.

Q: "No failing imports detected but build still fails" A: The tool only catches module resolution errors. Check for type-only import issues (import type) or ensure you're running with tsc --noEmit --traceResolution to capture all resolution attempts.

Q: Patches don't fix the issue? A: Some resolution failures require rootDirs configuration for virtual project structures, or you may need to adjust moduleResolution strategy (NodeNext vs bundler).

Contributing

See CONTRIBUTING.md

License

MIT (c) AdametherzLab

About

CLI that diagnoses and auto-fixes TypeScript module resolution errors by rewriting your tsconfig paths and baseUrl

Topics

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors