## TL;DR

Vitest resolves like Vite, not like Jest. Mirror your Vite aliases in the Vitest config, include the right extensions, and check whether the dependency needs inlining.

## Error

```text
Error: Failed to resolve import "@/components/Button" from "src/App.test.tsx". Does the file exist?
```

## Steps

1. Check `vitest.config.ts` (or vite.config.ts `test` block) for `resolve.alias` matching your tsconfig paths. Expected: `@` maps to `src`.
2. If the import is a bare package that fails, try `deps.inline: [/problem-lib/]` or `deps.web.transformAssets`. Expected: the dependency is processed instead of externalized.
3. Check file extensions: Vitest needs the real extension or a configured one. Expected: imports use extensions Vite understands.
4. Clear the Vite cache (`node_modules/.vite`) and re-run. Expected: stale pre-bundling is ruled out.
5- Re-run the single test file. Expected: the import resolves.

## When to use

- `Failed to resolve import` in Vitest specifically.
- The same import works in the dev server.

## When not to use

- Jest resolution errors (different resolver).
- Runtime `undefined` after a successful import (different bug).

## Tool compatibility

- Vitest 0.30 through latest; Vite 4/5.

## Variant phrasings

### Vitest cannot find module @/...

Alias misconfiguration; the most common cause.

### Vitest failed to resolve import of .css

CSS handling in tests; check `css: false` or mocks.

## Why it happens

Vitest reuses Vite's resolver, which differs from both Node and Jest in alias handling, extension rules, and dependency externalization.

## Edge cases

- `deps.interopDefault` fixes default-import interop for CJS deps.
- Monorepo workspace deps need aliases per package.
- `environment: 'jsdom'` vs `'node'` changes which globals exist, not resolution, but the errors look similar.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_SJh0f4Rk6l-rMBpQsRuy9Q
