# Import alias usage consistency

- **Pattern:** `ab-000234` (`ai-slop-code-drift.convention-drift.import-alias-consistency`)
- **Severity:** low
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-000234
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-000234)

## Why it matters

Mixed import styles — some files using `@/components/ui/button`, others using `../../../components/ui/button` — are a direct maintainability tax. Relative imports break silently when a file moves; alias imports are path-independent and survive directory reorganization. ISO 25010 maintainability flags this as a modifiability defect: every refactor that moves a file must also audit every relative import pointing at it. AI-generated code produces this drift because each session tends to copy the import style from whatever file it last read, producing a codebase where convention depends on which file the AI happened to open first.

## Severity rationale

Low because mixed import styles increase refactoring cost and error surface without causing runtime failures or security exposure in correctly-compiled code.

## Remediation

Set alias imports as the standard and convert relative parent imports with a one-time codemod. The ESLint rule `import/no-relative-parent-imports` prevents backsliding.

```ts
// Bad: breaks if src/features/auth/LoginForm.tsx moves
import { Button } from '../../../components/ui/button'

// Good: survives any directory reorganization
import { Button } from '@/components/ui/button'
```

Run `npx @antfu/ni && npx tsr` or `sed -i` to bulk-convert, then add to `.eslintrc`:

```json
{ "rules": { "import/no-relative-parent-imports": "error" } }
```

Verify `tsconfig.json` has `"paths": { "@/*": ["./src/*"] }` and `baseUrl` set so the alias resolves correctly at build time.

## Detection

- **ID:** `import-alias-consistency`
- **Severity:** `low`
- **What to look for:** Read `tsconfig.json` `compilerOptions.paths` to confirm at least one alias is defined (e.g., `@/*`). If aliases are defined, sample all source files for cross-directory imports (imports that traverse `..` OR use an alias). For each cross-directory import, classify it as alias-style (starts with a tsconfig paths prefix like `@/`) or relative-style (starts with `../`). Same-directory imports (`./sibling`) are EXCLUDED — they always use relative and are not drift. Count all and compute percentages.
- **Pass criteria:** Of all cross-directory imports, at least 80% use the same style (either all alias OR all relative). Report even on pass: "Dominant import style: [alias/relative] ([X]% of [Y] cross-directory imports)."
- **Fail criteria:** Neither style is at least 80% of cross-directory imports.
- **Skip (N/A) when:** `tsconfig.json` does not define `compilerOptions.paths` (no alias system to compare against).
- **Detail on fail:** `"Mixed import styles: alias 60% (45 imports), relative 40% (30 imports). Pick one and convert the rest."`
- **Remediation:** Mixed import styles make refactoring harder — moving a file with relative imports breaks everything; aliases are stable. Pick alias-style as the default:

  ```ts
  // Bad: relative import that breaks if the file moves
  import { Button } from '../../../components/ui/button'

  // Good: alias import that survives moves
  import { Button } from '@/components/ui/button'
  ```

  ESLint rule `import/no-relative-parent-imports` enforces this automatically.

## External references

- iso-25010 maintainability

Taxons: code-quality

HTML version: https://auditbuffet.com/patterns/ab-000234
