Packages That Ship TypeScript Types vs DefinitelyTyped
·PkgPulse Team
TL;DR
In 2026, 78% of the top 1000 npm packages ship their own TypeScript types, up from 45% in 2020. Bundled types are always better: they're versioned with the package, maintained by the same team, and never lag behind breaking changes. DefinitelyTyped (@types/) still has ~10,000 packages but should be considered a legacy fallback — for new projects, prioritize packages with built-in types.
Key Takeaways
- 78% of top 1000 packages now ship built-in TypeScript types (2026)
@types/lag problem: DefinitelyTyped types can be months behind the actual package- Version mismatch pain:
package@2.0with@types/package@1.9→ silent errors "types"field in package.json — how to check for built-in types- TypeScript-first packages tend to have better documentation and fewer runtime surprises
Built-In Types vs DefinitelyTyped
// Built-in types (best): types are IN the package
// package.json:
{
"name": "fastify",
"version": "4.24.0",
"types": "fastify.d.ts" // ← types ship with package
// OR:
"exports": {
".": {
"types": "./index.d.ts"
}
}
}
// DefinitelyTyped (@types/): types are a SEPARATE package
// npm install express
// npm install -D @types/express ← separate install, separate version
// The problem: express@4.18.2 + @types/express@4.17.21
// Package: 4.18.2 | Types: 4.17.21 → 1 minor version behind
// Can cause: missing types for new methods, wrong signatures
How to Check Which Type System a Package Uses
# Method 1: npm page
# npmjs.com/package/fastify — will show TypeScript badge if types bundled
# Method 2: Check package.json
npm view fastify --json | jq '.types, .typings, .exports'
# If any of these return a .d.ts path: built-in types ✅
# If all null: needs @types/ or has no types
# Method 3: Check package contents
npm pack fastify --dry-run | grep .d.ts
# Shows .d.ts files in the package
# Method 4: PkgPulse
# Health score includes TypeScript support indicator
# pkgpulse.com/compare/fastify-vs-express
# Quick check via TypeScript:
import fastify from 'fastify';
// If TypeScript finds types without @types/: built-in ✅
// If TypeScript errors: needs @types/ or no types available
Major Packages: Built-In Types ✅
// These packages ship their own types — no @types/ needed:
// Web frameworks:
import Fastify from 'fastify'; // fastify ✅
import { Hono } from 'hono'; // hono ✅
// import Koa from 'koa'; // ❌ needs @types/koa
// State management:
import { create } from 'zustand'; // zustand ✅
import { atom } from 'jotai'; // jotai ✅
import { proxy } from 'valtio'; // valtio ✅
// Data fetching:
import { useQuery } from '@tanstack/react-query'; // ✅
import { ofetch } from 'ofetch'; // ofetch ✅
// Validation:
import { z } from 'zod'; // zod ✅
import * as v from 'valibot'; // valibot ✅
// ORM:
import { drizzle } from 'drizzle-orm'; // drizzle-orm ✅
import { PrismaClient } from '@prisma/client'; // prisma (generated) ✅
// Build tools (cli only, but types for config):
// vite.config.ts: built-in types for defineConfig ✅
// Test runners:
import { describe, it, expect } from 'vitest'; // vitest ✅
// Jest: needs @types/jest ❌ (or jest/globals if configured)
// Logging:
import pino from 'pino'; // pino ✅
// Date:
import dayjs from 'dayjs'; // dayjs ✅
import { format } from 'date-fns'; // date-fns ✅
Packages That Still Need @types/
// DefinitelyTyped still needed for:
// Old guard (pre-TypeScript era):
npm install -D @types/express // express (old but stable)
npm install -D @types/node // Node.js built-ins (runtime types)
npm install -D @types/react // react (types are separate by design)
npm install -D @types/react-dom
// express: has been promised built-in types since v5, not yet shipped
// react: intentional separation from @types/react, maintained by community
// Testing:
npm install -D @types/jest // jest (if not using jest/globals)
npm install -D @types/mocha // mocha
// Utility libraries:
npm install -D @types/lodash // lodash
npm install -D @types/uuid // uuid (v9+ has built-in types actually)
// Note: @types/node is special — it's always needed for Node.js APIs
// even if you're using packages with built-in types
The Version Mismatch Problem
// Real example: express breaking types between versions
// package.json:
{
"dependencies": {
"express": "^4.18.0" // Installed: 4.18.2
},
"devDependencies": {
"@types/express": "^4.17.0" // Installed: 4.17.21
}
}
// Problem: express added new methods/changed signatures in 4.18
// @types/express@4.17.21 doesn't know about them
// TypeScript says: no error ✅
// Runtime: behavior differs from types ❌
// This happened with:
// - Node.js fetch types vs @types/node
// - react-router-dom between major versions
// - Several AWS SDK types
// Solution: lock @types/ versions tightly
// "@types/express": "4.17.21" ← exact, not ^
// Or better: pick packages with built-in types
TypeScript Adoption in npm: The Data
TypeScript type support across npm packages (2026):
Top 100 packages: 95% have types (bundled or @types/)
Top 1,000 packages: 89% have types
Top 10,000 packages: 78% have types
All packages: ~40% have types (long tail is JS-only)
Of packages WITH types:
- Bundled types: 78% (up from 45% in 2020)
- Only @types/: 22% (declining as packages migrate)
Why bundled types are growing:
1. TypeScript itself grew: ~68% of JS devs use TS (State of JS 2025)
2. Package authors feel pressure to support TypeScript properly
3. npm shows TS badge prominently → drives competitive behavior
4. tRPC/Zod pattern: end-to-end types REQUIRE bundled types to work
How to Check Type Quality (Not Just Presence)
// Having types isn't enough — type QUALITY matters
// Red flags in @types/ packages:
// ❌ Everything typed as `any`
declare function doThing(options: any): any;
// ❌ Missing generics
declare function useQuery(key: string, fn: Function): any;
// Should be:
declare function useQuery<T>(key: string, fn: () => Promise<T>): { data: T | undefined };
// ❌ Types in wrong export location (export default vs export =)
// Causes: "Module has no exported member" errors
// ✅ Good type quality signals:
// - Generics used throughout
// - Return types inferred from input types
// - Utility types used correctly (Partial, Required, Pick, Record)
// - TypeScript strict mode compatibility
// - Types tested in the package's own test suite (dts-jest or tsd)
tsconfig Best Practices with @types/
// tsconfig.json
{
"compilerOptions": {
// Only include @types/ packages you explicitly need
// Without this, TypeScript includes ALL installed @types/ automatically
"types": ["node", "jest"],
// Or: don't specify "types" and let TypeScript auto-discover
// Better for most projects
// Check type version compatibility:
"skipLibCheck": true, // Skip type checking of declaration files
// Use this if you hit type conflicts between @types/ packages
// Not ideal but sometimes necessary with complex dep trees
// Better alternative:
"skipLibCheck": false, // Keep it on, fix the root cause
}
}
Migrating Off DefinitelyTyped
# Check if a package now ships its own types (many did since 2022):
# uuid migrated in v9:
# Before: npm install uuid @types/uuid
# After (uuid v9+): npm install uuid ← no @types/ needed
npm view uuid --json | jq '.types'
# Returns: "dist/cjs/index.d.ts" ✅
# If a package you use added built-in types:
npm uninstall @types/package-name
npm install package-name@latest
# TypeScript should pick up the bundled types automatically
The Future: TypeScript-Native Packages
// Trend: packages written in TypeScript from day 1
// No .js + .d.ts dance — TypeScript source → distribution
// Tools that compile packages:
// tsup: builds both CJS and ESM with types from a single TypeScript source
// unbuild: used by Nuxt ecosystem packages
// pkgroll: Rollup-based, type-aware
// package.json pattern for TypeScript-native packages:
{
"main": "./dist/index.cjs",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"exports": {
".": {
"require": "./dist/index.cjs",
"import": "./dist/index.mjs",
"types": "./dist/index.d.ts"
}
}
}
// This is the modern standard — CJS + ESM + types, single package
Compare TypeScript support and package health on PkgPulse.
See the live comparison
View typescript vs. jsdoc on PkgPulse →