Findings & notices
A finding is a real problem that fails the audit (ok: false, exit 1). A notice is a coverage gap that does not fail by default. An unchecked specifier is one static analysis could not resolve (surfaced for transparency, never a failure).
Findings
Section titled “Findings”Every finding has a surface (types or runtime) and a kind:
| Kind | Surface | Meaning |
|---|---|---|
undeclared | types / runtime | The owning package is reachable on the surface but is not declared in any non-dev manifest field. |
missing-types | types | The package is declared but provides no resolvable declarations for the specifier (the headline bug — e.g. a .d.ts import('react') with react declared but no @types/react). |
unresolved | runtime | The package is declared but the specifier does not resolve to a file — typically a deep import of a subpath the dependency’s exports does not expose, or a missing target file. |
Each finding carries a suggestion with concrete remediation. Examples:
✗ types [undeclared] csstype (dist/index.d.ts) → declare "csstype" (or "@types/csstype" if it ships no types)
✗ types [missing-types] react (dist/index.d.ts) → "react" is declared but provides no resolvable declarations for "react"; add "@types/react" or a version that ships types
✗ runtime [unresolved] exporter/private (dist/index.js) → "exporter/private" does not resolve through declared "exporter" (subpath not exported, or the target file is missing)How to fix each
Section titled “How to fix each”undeclared(runtime): add the package todependencies(orpeerDependencies/optionalDependenciesif that fits its role).undeclared(types): add the package — or its@types/*companion if it ships no types of its own — todependencies(runtime-needed) ordevDependenciesis not enough if the type leaks into your published.d.ts; a type a consumer must resolve has to be a non-dev dependency.missing-types: declare the@types/*package, or upgrade the dependency to a version that bundles its own declarations.unresolved: stop importing the private subpath, or (if it should be public) ask the dependency to add it to itsexports. If it is your own subpath import that the dependency genuinely exports, this can indicate a version mismatch in the materialized tree.
Node builtins
Section titled “Node builtins”A node:-prefixed or bare builtin (fs, path, …) needs no declaration at run time, so it is never a runtime finding. On the type surface a builtin implies @types/node: if a declaration references a builtin and @types/node is not declared, that is an undeclared finding suggesting @types/node.
Notices
Section titled “Notices”A notice means a surface had nothing to analyze — emitted so “audited, clean” is never confused with “nothing audited”. Notices live in result.notices, print as ℹ, and do not fail the audit unless you pass --require-types.
| Kind | Surface | Meaning |
|---|---|---|
types-not-built | types | The manifest declares type declarations (a types/typings field, typesVersions, or an exports types condition) but none resolve from the package root — the build output looks missing. Build the package before auditing, or fix the declared types path. |
types-unreachable | types | The package ships .d.ts files but no manifest entry exposes them (no types field, no exports types condition, and exports encapsulates the package). Consumers cannot resolve its types — a likely packaging gap. |
A package that legitimately declares and ships no types (e.g. a Babel/PostCSS plugin) produces no notice. A fully-analyzed type surface produces no notice.
--require-types
Section titled “--require-types”Pass --require-types (CLI) to promote any coverage notice to a failure (exit 1) — useful in a monorepo gate where every TypeScript package is expected to ship resolvable types. Programmatically, inspect result.notices.length yourself.
Unchecked specifiers
Section titled “Unchecked specifiers”A specifier whose value is not a literal — a dynamic import(someVariable), a templated require() call, a createRequire result stored in a variable — cannot be statically resolved. Rather than drop it (a silent false negative), the tool records it in result.unchecked with a reason, printed as ?. Review these manually; they are not failures.
Ignoring intentional findings
Section titled “Ignoring intentional findings”Some findings are intentional — an optional/plugin import the code guards at run time, or a specifier static analysis cannot prove is fine. Suppress them with ignore rules (CLI --ignore, or a config file). Suppressed findings move to result.ignored, still print (— ignored), and never fail the audit — so suppressions stay auditable.
An IgnoreRule matches a finding when every field it sets equals the finding’s; an empty rule matches nothing:
{ "package": "optional-plugin" } // any finding for this package{ "specifier": "react/jsx-runtime", "surface": "types" } // this exact specifier, on the type surface{ "surface": "runtime", "kind": "unresolved" } // all unresolved runtime findingsA CLI --ignore <value> is shorthand for “match package === value OR specifier === value”.