Install and Use @types Packages
Learn how to find, install, and use @types packages to add type definitions for JavaScript libraries in your TypeScript project.
When you install a JavaScript library like lodash, express, or react, the actual code on disk is plain JavaScript. TypeScript needs type definitions to give you autocomplete, parameter checking, and inline errors for that library.
@types packages provide those definitions. They are community-maintained declaration files published under the @types scope on npm. Installing one takes a single command, and TypeScript discovers it automatically.
What @types Packages Contain
An @types package ships only declaration files, no JavaScript, no runtime code. When you install @types/lodash, you get a small tree of declaration files like this.
node_modules/@types/lodash/
index.d.ts
common/
array.d.ts
collection.d.tsThese files describe every function, parameter, and return type in lodash. TypeScript reads them during compilation and uses them to check your code. The files are erased during compilation and never appear in your output bundle.
Step 1: Check If the Library Already Has Types
Before reaching for @types, check whether the library bundles its own type definitions. Many modern packages ship types directly:
npm info express typesIf this returns a file path like ./index.d.ts, the package includes its own types and you do not need @types/express.
You can also look inside the package's node_modules folder for declaration files, or check its package.json for a types or typings field. If none of these exist, proceed to @types.
Step 2: Install the @types Package
Install the type definitions as a dev dependency:
npm install --save-dev @types/lodashOnce installed, TypeScript automatically discovers the types without any configuration change. You can immediately use the library with full type support, including autocomplete and argument checking on every call.
import _ from "lodash";
const padded = _.padStart("Hello", 20, " ");
// ^ string -- TypeScript knows the return type
const result = _.padStart(42, 20, " ");
// ^^
// Argument of type 'number' is not assignable to parameter of type 'string'.No extra configuration is needed. TypeScript scans node_modules/@types by default and picks up the declarations.
How TypeScript Discovers @types
TypeScript automatically includes every package under the typeRoots compiler option during compilation, with no import needed. The default typeRoots includes node_modules/@types:
{
"compilerOptions": {
"typeRoots": ["./node_modules/@types"]
}
}When TypeScript encounters an import from "lodash", it checks three places in order, stopping at the first match it finds. The table below shows that lookup order.
| Order | Where TypeScript looks |
|---|---|
| 1 | Types bundled with the lodash package itself |
| 2 | A matching @types/lodash package in node_modules/@types |
| 3 | Any custom typeRoots folders you have configured |
You can add your own folders to typeRoots for project-specific declarations:
{
"compilerOptions": {
"typeRoots": ["./node_modules/@types", "./src/types"]
}
}With this configuration, TypeScript also reads declaration files from src/types/. This is useful for typing untyped packages that have no community types.
The types Compiler Option
The types option controls which @types packages are automatically included. Without it, all @types packages in typeRoots are visible:
{
"compilerOptions": {
"types": ["node", "jest"]
}
}With "types": ["node", "jest"], only @types/node and @types/jest are automatically included. All other @types packages in node_modules are ignored unless explicitly imported.
This is useful when you want strict control over the global type environment, for example, preventing test types from leaking into your application code.
Installing the Library and Its Types Together
The library and its types are separate packages. You need both:
npm install lodash # Runtime code
npm install --save-dev @types/lodash # Type definitions onlyIf you forget the @types package, TypeScript shows a compiler error the moment you try to import the library, rather than letting the import through untyped.
Could not find a declaration file for module 'lodash'.
Try `npm install --save-dev @types/lodash` if it exists
or add a new declaration (.d.ts) file containing `declare module 'lodash';`The error message tells you exactly what to do. Run the suggested command, and the error disappears.
Common Patterns for Different Package Types
Not all packages follow the same naming. Here is how to find types for common scenarios:
| Package | Type package | Notes |
|---|---|---|
| lodash | @types/lodash | Standard pattern |
| express | @types/express | Standard pattern |
| react | @types/react | Still a separate package, not bundled with react |
| date-fns | (bundled) | Ships its own types, no @types package needed |
| jest | @types/jest | Testing frameworks use @types |
| node | @types/node | Node.js built-in APIs need @types/node |
| Scoped: @scope/pkg | @types/scope__pkg | Double underscore replaces slash |
For scoped packages, the slash is replaced with a double underscore. For example, @babel/core becomes @types/babel__core.
What to Do When @types Does Not Exist
If you run npm install --save-dev @types/some-package and get a 404, the community has not yet typed that package. You have two options:
- Quick shim: Create a minimal declaration that tells TypeScript the module exists, silencing the error while treating every import from it as any.
// types/some-package.d.ts
declare module "some-package";- Write real types: Create a full declaration file describing the parts of the API you actually use, using the same
declare modulepattern covered in ambient declarations in TypeScript.
Keeping @types Up to Date
@types packages are versioned separately from the libraries they describe. It is possible for the types to drift from the actual library API.
Run npm outdated periodically to see if newer versions of @types packages are available. The command lists every dependency where the installed version trails the latest published release.
npm outdatedThe output shows the currently installed version next to the latest one, so you can see at a glance which type packages have fallen behind.
Package Current Wanted Latest
@types/lodash 4.14.0 4.14.1 4.14.2Update them like any other dev dependency, using the @latest tag to jump straight to the newest published version instead of manually editing the version number in package.json.
npm install --save-dev @types/lodash@latestIf a library has a major version bump, check whether its @types counterpart also has a corresponding major version. The @types package version typically mirrors the library's major and minor version.
Rune AI
Key Insights
- Install @types packages with npm install --save-dev @types/package-name.
- Always install @types as devDependencies, never as production dependencies.
- TypeScript automatically discovers types in node_modules/@types.
- Many popular packages now bundle their own types, making @types unnecessary.
- Use typeRoots in tsconfig.json to add custom type declaration folders.
Frequently Asked Questions
What is the difference between a package and its @types counterpart?
Do I install @types as a dependency or devDependency?
What if no @types package exists for the library I need?
Conclusion
@types packages are the easiest way to add type safety to JavaScript dependencies. The workflow is simple: install the library, install its @types counterpart as a devDependency, and start coding with full autocomplete and type checking. TypeScript discovers them automatically through node_modules/@types and typeRoots.
More in this topic
TypeScript Compiler Explained
The TypeScript compiler (tsc) turns .ts files into .js files while checking types. Learn what it does, how to use it, and how it fits your workflow.
Set Up ESLint for TypeScript
Install and configure ESLint with typescript-eslint to catch bugs and enforce consistent code style in your TypeScript project.
Pick Utility Type in TypeScript
Pick creates a new type by selecting only the properties you name from an existing type. Use it to build focused types for specific views, API responses, or function parameters.