← Back to Fixes

TypeScript in 2026: Install & Configure with Node.js 20+

Install the latest TypeScript on Node 20 LTS, align @types/node and @supabase/supabase-js, and fix the errors after a TS upgrade.

The search query "npm typescript latest version" usually ends with a broken build. You run npm install typescript@latest, and the next npm run build throws one of:

bash
src/lib/supabase.ts:3:23 - error TS2307: Cannot find module '@types/node' or its corresponding type declarations.

or, the moment you touch the Supabase client:

ts
const { data, error } = await supabase.auth.getSession()
bash
Property 'auth' does not exist on type 'SupabaseClient<Database, PublicSchemaName>'.

It happens in npm run dev, npm run build, and in CI (Vercel/GitHub Actions) — especially in projects that started on Node.js 16 or 18, or where package.json has a stale engines field. The behavior is identical on macOS, Linux, and Windows.

The invariant that explains every symptom#

TypeScript's type system is only as safe as the type definitions it reads. It erases all types at compile time and adds no runtime checks. So when a TypeScript upgrade breaks your build, the cause is always a compile-time definition mismatch — never a runtime enforcement change.

Three things must move together, or you get the errors above:

  1. The TypeScript version itself.
  2. @types/node — the type definitions for Node.js APIs (Buffer, process, etc.). TypeScript 5.x tightened module resolution, so projects that used to get these transitively now need them installed explicitly.
  3. @supabase/supabase-js — its type definitions are versioned separately from the runtime. An outdated client paired with a newer TS resolver produces Property 'auth' does not exist.

npm's engines field is a warning by default, not a hard block — so if you see install failures, look at a package.json engines mismatch or a peer-dependency conflict, not at Node.js itself.

The alignment fix#

bash
# 1. Land on Node.js 20.x LTS
node -v
nvm install 20 && nvm use 20
 
# 2. Move TypeScript, the Node types, and the Supabase client forward together
npm install typescript@latest @types/node@latest @supabase/supabase-js@latest
 
# 3. Declare what you actually run
# in package.json:
#   "engines": { "node": ">=20.0.0" }

Then make tsconfig.json match what Next.js's bundler expects. create-next-app ships these defaults; using NodeNext in a Next.js project breaks resolution because Next.js is not a Node.js ESM loader.

json
{
  "compilerOptions": {
    "target": "ES2022",
    "lib": ["ES2022", "DOM"],
    "module": "esnext",
    "moduleResolution": "bundler",
    "esModuleInterop": true,
    "skipLibCheck": true,
    "strict": true,
    "noEmit": true,
    "jsx": "preserve",
    "incremental": true,
    "paths": { "@/*": ["./src/*"] }
  },
  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
  "exclude": ["node_modules"]
}

"module": "esnext" + "moduleResolution": "bundler" is the single change that resolves most "Cannot find module" errors after a TS bump, because it matches what webpack and Turbopack actually do.

Verify everything lines up#

bash
node -v && npm -v && npx tsc --version
# v20.x.x
# 10.x.x
# Version 5.x.x
 
npx tsc --noEmit
# Found 0 errors.

If Cannot find module '@types/node' persists:

bash
npm install --save-dev @types/node@latest

If Property 'auth' does not exist persists, the Supabase client is still stale:

bash
npm ls @supabase/supabase-js
npm install @supabase/supabase-js@latest

Two stubborn variants#

npm ERR! peer optional dependency failed@next/eslint-plugin-next has a peer range that does not yet cover the TypeScript you installed. Fix with npm install --save-dev @next/eslint-plugin-next@latest; npm 9+ auto-resolves compatible versions, no manual downgrade needed.

Jest: Cannot find module 'ts-jest'ts-jest before v29 does not understand TypeScript 5.x. Update jest.config.js to preset: 'ts-jest' and install ts-jest@^29 @types/jest@^29.

Keep it from happening again#

  • Declare "engines": { "node": ">=20.0.0" } in package.json so a mismatched runtime fails fast.
  • Use npm ci (not npm install) in CI to enforce the lockfile.
  • Run npm ls typescript @supabase/supabase-js @types/node before deploying to catch version drift.
  • In Next.js projects, keep "module": "esnext" and "moduleResolution": "bundler" — they are the create-next-app defaults and what the bundler expects.

Related fixes & guides