error TS2792: Cannot find module 'ajv'. Did you mean to set the 'moduleResolution' option to 'nodenext', or to add aliases to the 'paths' option? is reported for a package import that would resolve under Node.js rules but fails under the resolution mode the config is using. The message is a hint that the mode is the problem.
The usual cause is a jsconfig.json with "module": "es2022" (or esnext) and no moduleResolution. In TypeScript 5.9 that combination falls back to classic, a lookup from before npm packages were the norm: relative imports work, packages that ship their own types are not found. (@types packages are still found, which is why the error can appear for one package and not another.)
At a glance
| Code | TS2792 |
|---|---|
| Message | Cannot find module '{0}'. Did you mean to set the 'moduleResolution' option to 'nodenext', or to add aliases to the 'paths' option? |
| TypeScript's category | error |
| Listed under | Modules and imports |
| Depends on | moduleResolution, module |
| In .js files | Reported when the file is checked: checkJs in jsconfig.json, or // @ts-check at the top of the file |
The message is TypeScript's own text from its diagnostic messages file (Apache-2.0); {0} is filled in by tsc for each error.
What it looks like
import Ajv from "ajv";error TS2792: Cannot find module 'ajv'. Did you mean to set the 'moduleResolution' option to 'nodenext', or to add aliases to the 'paths' option?
export const ajv = new Ajv();jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2022",
"module": "es2022",
"types": []
},
"include": ["*.js"]
} What causes it
moduleises2015toesnextandmoduleResolutionis not set, so it defaults toclassic.moduleResolutionis set toclassicexplicitly in an old config.
How to fix it
Set moduleResolution, or use module nodenext
For code a bundler builds, add "moduleResolution": "bundler". For code Node.js runs directly, use "module": "nodenext", which implies moduleResolution: "nodenext". Either way packages in node_modules resolve the way the runtime or bundler resolves them.
import Ajv from "ajv";
export const ajv = new Ajv();jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2022",
"module": "es2022",
"types": [],
"moduleResolution": "bundler"
},
"include": ["*.js"]
} Under TypeScript 6.0 and 7.0
Every example on this page also runs under TypeScript 6.0.3 and 7.0.2 when this site is built. One of them reports something different from 5.9.3, the version the page describes; the ✗ on its badge links to its entry below.
moduleResolution: classic is gone
The pattern: A package import (import Ajv from "ajv") with module: es2022 and no moduleResolution.
Why: With that module, 5.9 fell back to classic resolution, which does not look in node_modules (TS2792). The 6.0 release notes say classic has been removed, so 6.0 and 7.0 resolve the package and report nothing. Source: TypeScript 6.0 release notes: Deprecated: --moduleResolution classic.
module set without moduleResolution: the old classic lookup validate.js
- TypeScript 5.9.3
validate.js(2,17): error TS2792: Cannot find module 'ajv'. Did you mean to set the 'moduleResolution' option to 'nodenext', or to add aliases to the 'paths' option?
- TypeScript 6.0.3differs from 5.9.3
No errors.
- TypeScript 7.0.2differs from 5.9.3
No errors.
What works in every version: Set moduleResolution to bundler or nodenext.
The example moduleResolution bundler finds the package in node_modules on this page shows it, with the same result under every version.
Gotchas
bundlerresolution accepts imports without file extensions; Node.js itself does not. Pick the one that matches what runs the code.- If the import is an alias your bundler defines, the second half of the hint applies: add it to
paths.
Sources
- TSConfig Reference: moduleResolution · TypeScript
- Modules Reference: classic · TypeScript handbook
- diagnosticMessages.json (TypeScript 5.9.3) · TypeScript on GitHub
Last reviewed 20 October 2026.