TypeScript v6 is a major release of the TypeScript language that serves as a necessary bridge to the Go-powered TypeScript v7 coming soon. Because of this, most of the changes introduced are meant to align your codebase for a smooth adoption of v7 when it eventually arrives.
The introduced changes include new tsconfig.json conventions, built-in types from the latest ECMAScript specification, and numerous deprecations. This article will give a breakdown of the major changes. It also aims to serve as a migration guide from v5.x to v6. Let’s get started.
The Replay is a weekly newsletter for dev and engineering leaders.
Delivered once a week, it's your curated guide to the most important conversations around frontend dev, emerging AI tools, and the state of modern software.
First, install the new version into your project. The way to do that is to run the following:
npm install typescript@6
This changes the TypeScript version in your package.json to 6.0.x and replaces the TypeScript package inside your node_modules folder with the new version. Installing v6 also instructs your code editor to typecheck your code with the new recommendations of the version.
After installing v6, your code editor will highlight a few errors in your tsconfig.json file since some v5 config options got deprecated.
If you don’t want to fix all those deprecations at the moment, there is a new TypeScript compiler option called ignoreDeprecations that allows you to ignore the errors. Setting this is important for projects that need a more gradual migration to v6.
Note: TypeScript will completely end support for those deprecated options in v7. You would not be able to ignore them anymore.
To ignore the deprecations, add the following to your tsconfig.json file:
{
"compilerOptions": {
"ignoreDeprecations": "6.0"
}
}
Remember to remove this configuration after you have fully migrated to using appropriate v6 compiler options.
While v6 introduces other features, this section highlights the breaking changes. These are new conventions that are necessary to get v6 working.
Note: To skip this step-by-step migration process, check out this codemod (ts5to6), which can automatically migrate your codebase.
tsconfig.json now defaults to []In this new version, types now defaults to an empty array. In previous versions, setting types was optional. By default in v5, tsc used the types inside the node_modules/@types folder for ambient global types (e.g., process, __dirname in Node.js), and explicitly setting types was optional.
However, the v5 behavior could pull in hundreds or thousands of declaration files in node_module/@types/* that are not needed for typechecking. For this reason, the better approach is for devs to explicitly set types for global types. According to TypeScript docs, this change can potentially improve build-time by 20-50%:
{
"compilerOptions": {
"types": ["node", "vite/client"]
}
}
To retain the v5 behavior, and include all the types in the node_modules/@types folder, set the types to "*":
{
"compilerOptions": {
"types": ["*"]
}
}
lib: ["DOM" now contains DOM.Iterable and dom.AsyncIterablelib is a TypeScript configuration option that allows devs to specify which ECMAScript APIs should be allowed for that particular project. For projects that run on the browser, the typical lib option looked like this:
{
"compilerOptions": {
"lib": ["DOM", "DOM.Iterable"]
}
}
DOM.iterable existed and was separate from DOM because not all browsers supported iteration methods on DOM collections (NodeList or HTMLCollection) in the past. DOM.asynciterable, on the other hand, is a lib array option for async iteration of DOM APIs.
With v6, both DOM.Iterable and DOM.AsyncIterable types are now inside DOM, so there is no need to include them separately. This is because every major browser already implements these APIs.
So, use DOM like so:
{
"compilerOptions": {
"lib": ["DOM"]
}
}
While you can still explicitly list DOM.iterable and DOM.AsyncIterable in lib, those are now empty declarations. The main type definitions are inside DOM.
rootDir now defaults to '.'rootDir is a config option that specifies to tsc the root of a project’s source files. In v5, the default value of rootDir was the common path of all non-declaration input files. However, this default behavior was not the most optimal as tsc had to spend some time analyzing the file structure of a project and inferring the rootDir.
Now in v6, the default rootDir is any path that contains the tsconfig.json which is typically the root directory ('.'). TypeScript will only try to infer the rootDir when a project is compiled on the CLI without a tsconfig.json file.
If you relied on TypeScript inferring the rootDir in your project, set it to src folder (or wherever your source files are):
{
"compilerOptions": {
"rootDir": "./src"
}
}
baseUrl from the tscofig.json filebaseUrl is typically used to set the base path for path aliases in TypeScript.
For example:
{
"compilerOptions": {
"baseUrl": "./src/services",
"paths": {
"@mail": ["./mail/*"]
}
}
}
You can then import from the file "./src/services/mail.message.ts" without writing the full path:
// This works import sendMessage from '@mail/message.js'; // Instead of import sendMessage from './src/services/mail/message.js';
However, baseUrl is also considered a lookup root for resolving modules which could cause devs to import from files that they didn’t intend to. In v6, baseUrl is now deprecated. TypeScript v6 recommends writing out the full path when specifying path aliases. So, the tsconfig.json above is changed to:
{
"compilerOptions": {
"paths": {
"@mail": [".src/services/mail/*"]
}
}
}
strict is set to true by defaultThe strict compiler option is now set to true by default. This is because most devs write TypeScript with strict mode on, so it makes sense as a default option. You can now remove the strict setting in your config file as its true by default, or explicitly set strict to false if you relied on the default v5 behavior.
{
"compilerOptions": {
"strict": "false"
}
}
Apart from the specified breaking changes in the previous section, TypeScript v6 includes new features that did not exist before. This section goes over the most important ones.
The Node.js subpath imports feature allows developers to create path aliases for sub-directories in Node.js. This is specified inside package.json. For example:
// package.json
{
"name": "random-app",
"type": "module",
"imports": {
"#data/*": "./src/data/*"
}
}
And one can import a module into any file of their choice:
import data from '#data/index.js'
Note: Node.js subpath imports should not be confused with TypeScript path aliases which are admittedly similar but specified inside tsconfig.json.
However one could not use just # for a subpath in previous versions of Node.js:
// package.json
// Does not work
{
"name": "random-app",
"type": "module",
"imports": {
"#/*": "./src/data/*"
}
}
In v24.14, Node.js added support for #/ imports. Now with TypeScript v6, this feature is available to TypeScript users as well. All you have to do is set the moduleResolution of your project to nodenext or bundler.
// tsconfig.json
{
"compilerOptions": {
"moduleResolution": "nodenext" // or "bundler"
}
}
target and lib now have the option of ES2025target is the config setting that tells the compiler available APIs in the targeted runtime, so TypeScript can allow those APIs for developing the project. It also instructs the compiler to down-level syntax where appropriate.
target and lib now have the newly introduced option of ES2025. This new option provides types for ECMAScript APIs added to the language recently like Promise.try(), new Set methods, and so on. ES2025 represents the API standards available in major JavaScript runtimes currently.
In the v6 TypeScript config file, the default value of module is now ESNext. module is the config option that sets the module system a TypeScript project will use.
Also the default target is now ES2025. If migrating, check if you relied on previous default module and target values, and adjust fittingly.
Temporal is an upcoming replacement for the often criticized Date object in JavaScript (responsible for working with date and time in the language).
Here is an example of the Temporal syntax:
const now = Temporal.Now.instant;
console.log("Current Time: ", now);
In TypeScript v6, you can now use the Temporal API if you set target to ESNext, or use ESNext as a lib array option.
While Temporal is not yet supported on all major browsers and runtimes (at the time of writing), it has been gaining adoption and will surely be covered by all the necessary runtimes soon.
RegExp.escape()The RegExp.escape() method is used to sanitize strings of any potential Regular Expression syntax characters. This is so that the sanitized string can in turn be safely used as a literal pattern for a RegExp constructor. For example:
const removeDomain = (text: string, domainName: string) => {
const sanitized = RegExp.escape(domainName);
return text.replace(new RegExp(`https?://${sanitized}(?=/)`, "g"), "");
};
After setting ES2025 as an option for the lib array, one can use the new RegExp.escape() API in JavaScript. As a relatively newly added feature in JavaScript, TypeScript v6 extends type checking for it, to TypeScript users.
TypeScript v6 deprecated some config options. Here are the most important ones (excluding the removal of baseUrl already discussed in a previous section).
"target": "ES5" and --downlevelIteration flag: The --downlevelIteration CLI flag used to work together with "target": "ES5" to make sure modern iteration methods like for...of are transpiled to ES5 syntax. However, there is no more need for that. Every major browser implements ES6+ APIs so it makes sense that the target option of ES5 is now deprecated.--moduleResolution node and --moduleResolution classic: The node (aka node10) and classic options for --moduleResolution are now deprecated as the JavaScript ecosystem has evolved past these old module resolution algorithms.--module options of amd, umd, systemjs, and none: Those flag options are deprecated in v6 as they were only important when browsers lacked native module support. none is also deprecated because its use was never clearly defined and led to confusion.--alwaysStrict false: All TypeScript code in v6 is by default in strict mode, and setting "strict": "false" is also the toggle for setting --alwaysStrict to false. Hence one can just control for strictness with strict toggle.--esModuleInterop false and --allowSyntheticDefaultImports false: These flags are now set true as the default behavior. They allow devs to seamlessly import CommonJS modules into ES Modules.outFile config option: This is a config option that makes tsc compile the project into a single JavaScript file. However, third-party bundlers now do a faster and better job of this with far more configurability.module syntax for namespaces: TypeScript allowed creating namespaces with a module keyword before. That no longer works in this new version. Devs, however, can still use the declare module syntax for declaring ambient modules.tsconfig.json exists: In v5, if you ran tsc ./file.ts, TypeScript compiled that file, ignoring any existing config file in the folder containing file.ts. In v6, TypeScript will now use any available config file in the same folder. TypeScript will also no longer run if one specifies CLI flags (--noEmit, --strict, etc) for compiling a file when a tsconfig.json file is available. You can disable this v6 behavior using the --ignoreConfig flag.This article is not an exhaustive list of all the changes introduced in v6, instead these are the ones that are most likely to affect a lot of projects. There are still other changes like types for upsert feature of JavaScript Maps, and some others.
Note that Typescript’s reference docs have not been fully updated to reflect the new v6 config option behaviors (at the time of writing). However, hopefully, this guide helps make your migration process frictionless.
LogRocket lets you replay user sessions, eliminating guesswork by showing exactly what users experienced. It captures console logs, errors, network requests, and pixel-perfect DOM recordings — compatible with all frameworks, and with plugins to log additional context from Redux, Vuex, and @ngrx/store.
With Galileo AI, you can instantly identify and explain user struggles with automated monitoring of your entire product experience.
Modernize how you understand your web and mobile apps — start monitoring for free.

Learn how Vite+ unifies Vite, Vitest, Oxlint, Oxfmt, Rolldown, and Node.js management in one CLI.

AI companies are buying developer tools as coding agents turn runtimes, package managers, and linters into strategic infrastructure.

Learn how AI-assisted development governance uses rules, agents, hooks, and protocols to help AI coding tools produce safer, more consistent code.

A step-by-step guide to building your first MCP server using Node.js, covering core concepts, tool design, and upgrading from file storage to MySQL.
Hey there, want to help make our blog better?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up now