TypeScript upgraded to 6.0.2 across n8n monorepo
TypeScript 6.0.2 is now the standard across the n8n monorepo, with configuration updates to handle new compiler defaults around type auto-inclusion, directory inference, and deprecation warnings.
TypeScript 6.0.2 has arrived in the n8n monorepo, bringing stricter defaults that required updates across 23 configuration files to keep the build pipeline healthy.
The upgrade surfaces several breaking changes in TypeScript 6. Previously, projects could rely on automatic type inclusion from @types/* packages and implicit rootDir inference. TypeScript 6 now requires explicit configuration: packages using Jest or Node types must declare them explicitly, and rootDir must be specified when outDir is absent. Packages built with Vite moved from outDir declarations to noEmit:true, since their builds are handled by the bundler rather than tsc.
Type safety improvements in TypeScript 6 also caught real issues. Property access on a never type is now an error — this triggered fixes in log streaming code that had relied on the previous lenient behavior. WebSocket.send() now expects a narrower Uint8Array type, requiring a cast in the CRDT transport layer.
Several deprecation paths remain for future work. The moduleResolution:node and module:umd settings are deprecated, and noUncheckedSideEffectImports defaults to true under strict mode. These are flagged but deferred to separate efforts tracked in Linear.
The upgrade touches every major area: the CLI, editor-ui, design system, codemirror language packages, and shared TypeScript configuration templates. Once the migration stabilizes, developers gain access to TypeScript 6's improved type inference and faster compilation.
View Original GitHub Description
Summary
| What changed in TS 6 | Changes made to adapt |
|---|---|
types defaults to [] instead of auto-including all @types/* | Added types: ["node", "jest"] to codemirror-lang and stylelint-config packages (longer term, these FE packages should stop using Jest!). Switched @n8n/json-schema-to-zod to extend tsconfig.backend.json which already carries them. Excluded test helper dirs from nodes-base's build tsconfig. Added tsconfig.scripts.json to @n8n/extension-sdk to cover the orphaned scripts/ directory that uses Node built-ins. |
rootDir defaults to the tsconfig dir instead of being inferred from sources | Added explicit rootDir: "src" to the three standalone @n8n/json-schema-to-zod build configs. Added rootDir: "." to ts-jest's inline tsconfig in the root jest.config.js to fix TS5011 when ts-jest compiles a single file (e.g. globalSetup.ts) in isolation. |
Cross-package path aliases fail when outDir is set without rootDir | Replaced outDir: "dist" with noEmit: true in design-system, rest-api-client, editor-ui, and storybook tsconfigs (all use Vite/tsdown for building, never tsc) |
noUncheckedSideEffectImports enabled by default under strict | Set to false in both base tsconfig.common.json and modern/tsconfig.json (will need to be a separate dedicated effort) |
moduleResolution: node and module: umd are deprecated | Added ignoreDeprecations: "6.0" to the two shared base configs and two standalone configs that use these settings (will need to be a separate dedicated effort) |
| DOM lib updated with new interface members | Edited a polyfill in editor-ui/__tests__/setup.ts |
Uint8Array is now Uint8Array<ArrayBufferLike>; WebSocket.send() requires Uint8Array<ArrayBuffer> | Type cast at the call site in @n8n/crdt (will need to be a separate dedicated to propagate through Y.js call sites, best done by folks who know this package) |
Property access on never is now a type error | Cast body in the default branch of an exhaustive switch in log-streaming.controller.ts |
Related Linear tickets, Github issues, and Community forum posts
Separate dedicated efforts are tracked here:
- https://linear.app/n8n/issue/CAT-2713
- https://linear.app/n8n/issue/CAT-2714
- https://linear.app/n8n/issue/CAT-2715
Review / Merge checklist
- PR title and summary are descriptive. (conventions) <!-- **Remember, the title automatically goes into the changelog. Use `(no-changelog)` otherwise.** -->
- Docs updated or follow-up ticket created.
- Tests included. <!-- A bug is not considered fixed, unless a test is added to prevent it from happening again. A feature is not complete without tests. -->
- PR Labeled with
Backport to Beta,Backport to Stable, orBackport to v1(if the PR is an urgent fix that needs to be backported)