From cb3f54f1921fcdd9ae8529e5f7a73c14be8bc449 Mon Sep 17 00:00:00 2001 From: Chris Arderne Date: Wed, 22 Jul 2026 13:24:24 +0100 Subject: [PATCH 1/4] feat(core,cli): add node-24 and node-26 runtimes, deprecate experimental aliases Promote node-24 and node-26 to supported runtime options in trigger.config.ts. The experimental-node-24 and experimental-node-26 names remain as deprecated aliases that resolve to their replacements and emit a deprecation warning. --- .changeset/node-24-26-runtimes.md | 15 +++++++++++ docs/snippets/node-versions.mdx | 17 ++++++------ packages/cli-v3/src/config.test.ts | 6 ++++- packages/cli-v3/src/config.ts | 9 ++++--- packages/core/src/v3/build/runtime.test.ts | 31 +++++++++++++--------- packages/core/src/v3/build/runtime.ts | 16 ++++++++--- packages/core/src/v3/schemas/build.ts | 3 +++ 7 files changed, 70 insertions(+), 27 deletions(-) create mode 100644 .changeset/node-24-26-runtimes.md diff --git a/.changeset/node-24-26-runtimes.md b/.changeset/node-24-26-runtimes.md new file mode 100644 index 00000000000..4a2f7ebc9a8 --- /dev/null +++ b/.changeset/node-24-26-runtimes.md @@ -0,0 +1,15 @@ +--- +"@trigger.dev/core": patch +"trigger.dev": patch +--- + +Add `node-24` and `node-26` as supported `runtime` options in `trigger.config.ts`. The `experimental-node-24` and `experimental-node-26` names are now deprecated aliases and emit a deprecation warning; switch to `node-24` / `node-26` instead. + +```ts +import { defineConfig } from "@trigger.dev/sdk"; + +export default defineConfig({ + runtime: "node-24", + project: "", +}); +``` diff --git a/docs/snippets/node-versions.mdx b/docs/snippets/node-versions.mdx index 76bc386f810..f71c2874f7d 100644 --- a/docs/snippets/node-versions.mdx +++ b/docs/snippets/node-versions.mdx @@ -1,13 +1,9 @@ Trigger.dev runs your tasks on specific Node.js versions: -### v3 - -- Node.js `21.7.3` - -### v4 - - Node.js `21.7.3` (default) - Node.js `22.16.0` (`node-22`) +- Node.js `24.18.0` (`node-24`) +- Node.js `26.4.0` (`node-26`) - Bun `1.3.3` (`bun`) You can change the runtime by setting the `runtime` field in your `trigger.config.ts` file. @@ -16,8 +12,13 @@ You can change the runtime by setting the `runtime` field in your `trigger.confi import { defineConfig } from "@trigger.dev/sdk"; export default defineConfig({ - // "node", "node-22" or "bun" - runtime: "node-22", + // "node", "node-22", "node-24", "node-26" or "bun" + runtime: "node-24", project: "", }); ``` + + + The `experimental-node-24` and `experimental-node-26` runtime names are deprecated. Use `node-24` + and `node-26` instead. + diff --git a/packages/cli-v3/src/config.test.ts b/packages/cli-v3/src/config.test.ts index 910b2362420..cafee4b9a3d 100644 --- a/packages/cli-v3/src/config.test.ts +++ b/packages/cli-v3/src/config.test.ts @@ -33,6 +33,10 @@ async function createProject(runtime?: string) { describe("loadConfig runtime", () => { it.each([ + ["node", "node"], + ["node-22", "node-22"], + ["node-24", "node-24"], + ["node-26", "node-26"], ["experimental-node-24", "node-24"], ["experimental-node-26", "node-26"], ] as const)("normalizes %s before returning the resolved config", async (runtime, expected) => { @@ -47,7 +51,7 @@ describe("loadConfig runtime", () => { await expect(loadConfig({ cwd, warn: false })).resolves.toMatchObject({ runtime: "node" }); }); - it.each(["node-24", "node-26", "node-23"])( + it.each(["node-23"])( "rejects unsupported public runtime %s while loading config", async (runtime) => { const cwd = await createProject(runtime); diff --git a/packages/cli-v3/src/config.ts b/packages/cli-v3/src/config.ts index 8b162fbc409..2e7ffdee509 100644 --- a/packages/cli-v3/src/config.ts +++ b/packages/cli-v3/src/config.ts @@ -8,7 +8,8 @@ import type { import type { ResolvedConfig } from "@trigger.dev/core/v3/build"; import { DEFAULT_RUNTIME, - isExperimentalConfigRuntime, + deprecatedRuntimeReplacement, + isDeprecatedConfigRuntime, resolveBuildRuntime, } from "@trigger.dev/core/v3/build"; import * as c12 from "c12"; @@ -184,9 +185,11 @@ async function resolveConfig( const configuredRuntime = overrides?.runtime ?? config.runtime ?? defaultRuntime; const runtime = resolveBuildRuntime(configuredRuntime); - if (warn && isExperimentalConfigRuntime(configuredRuntime)) { + if (warn && isDeprecatedConfigRuntime(configuredRuntime)) { prettyWarning( - `The "${configuredRuntime}" runtime is experimental and may change before general availability.` + `The "${configuredRuntime}" runtime is deprecated. Use "${deprecatedRuntimeReplacement( + configuredRuntime + )}" instead.` ); } diff --git a/packages/core/src/v3/build/runtime.test.ts b/packages/core/src/v3/build/runtime.test.ts index 2c166f2b01f..0073c15b22a 100644 --- a/packages/core/src/v3/build/runtime.test.ts +++ b/packages/core/src/v3/build/runtime.test.ts @@ -1,31 +1,38 @@ import { describe, expect, it } from "vitest"; import { BuildManifest, BuildRuntime, ConfigRuntime, WorkerManifest } from "../schemas/build.js"; -import { isExperimentalConfigRuntime, resolveBuildRuntime } from "./runtime.js"; +import { isDeprecatedConfigRuntime, resolveBuildRuntime } from "./runtime.js"; describe("runtime configuration", () => { - it.each(["node", "node-22", "experimental-node-24", "experimental-node-26", "bun"] as const)( - "accepts %s as a public config runtime", - (runtime) => { - expect(ConfigRuntime.parse(runtime)).toBe(runtime); - } - ); + it.each([ + "node", + "node-22", + "node-24", + "node-26", + "experimental-node-24", + "experimental-node-26", + "bun", + ] as const)("accepts %s as a public config runtime", (runtime) => { + expect(ConfigRuntime.parse(runtime)).toBe(runtime); + }); it.each([ ["experimental-node-24", "node-24"], ["experimental-node-26", "node-26"], ["node", "node"], ["node-22", "node-22"], + ["node-24", "node-24"], + ["node-26", "node-26"], ["bun", "bun"], ] as const)("normalizes %s to %s", (runtime, expected) => { expect(resolveBuildRuntime(runtime)).toBe(expected); }); it.each(["node-24", "node-26"] as const)( - "keeps internal runtime %s out of the public config schema", + "accepts internal runtime %s in both public and internal schemas", (runtime) => { - expect(ConfigRuntime.safeParse(runtime).success).toBe(false); + expect(ConfigRuntime.safeParse(runtime).success).toBe(true); expect(BuildRuntime.safeParse(runtime).success).toBe(true); - expect(() => resolveBuildRuntime(runtime)).toThrowError(/Unsupported runtime/); + expect(resolveBuildRuntime(runtime)).toBe(runtime); } ); @@ -36,12 +43,12 @@ describe("runtime configuration", () => { }); it.each(["experimental-node-24", "experimental-node-26"] as const)( - "keeps %s out of internal runtime schemas", + "treats %s as a deprecated alias kept out of internal runtime schemas", (runtime) => { expect(BuildRuntime.safeParse(runtime).success).toBe(false); expect(BuildManifest.shape.runtime.safeParse(runtime).success).toBe(false); expect(WorkerManifest.shape.runtime.safeParse(runtime).success).toBe(false); - expect(isExperimentalConfigRuntime(runtime)).toBe(true); + expect(isDeprecatedConfigRuntime(runtime)).toBe(true); } ); }); diff --git a/packages/core/src/v3/build/runtime.ts b/packages/core/src/v3/build/runtime.ts index 10fcc962b78..21d56d258be 100644 --- a/packages/core/src/v3/build/runtime.ts +++ b/packages/core/src/v3/build/runtime.ts @@ -6,14 +6,24 @@ import { homedir } from "node:os"; export const DEFAULT_RUNTIME = "node" satisfies BuildRuntime; -export type ExperimentalConfigRuntime = "experimental-node-24" | "experimental-node-26"; +export type DeprecatedConfigRuntime = "experimental-node-24" | "experimental-node-26"; -export function isExperimentalConfigRuntime( +export function isDeprecatedConfigRuntime( runtime: unknown -): runtime is ExperimentalConfigRuntime { +): runtime is DeprecatedConfigRuntime { return runtime === "experimental-node-24" || runtime === "experimental-node-26"; } +/** Maps a deprecated runtime alias to the runtime that should be used instead. */ +export function deprecatedRuntimeReplacement(runtime: DeprecatedConfigRuntime): BuildRuntime { + switch (runtime) { + case "experimental-node-24": + return "node-24"; + case "experimental-node-26": + return "node-26"; + } +} + export function resolveBuildRuntime(runtime: unknown): BuildRuntime { const parsedRuntime = ConfigRuntime.safeParse(runtime); diff --git a/packages/core/src/v3/schemas/build.ts b/packages/core/src/v3/schemas/build.ts index 1ab5b5b8169..52cae0b2385 100644 --- a/packages/core/src/v3/schemas/build.ts +++ b/packages/core/src/v3/schemas/build.ts @@ -16,6 +16,9 @@ export type BuildTarget = z.infer; export const ConfigRuntime = z.enum([ "node", "node-22", + "node-24", + "node-26", + // Deprecated aliases, kept for backwards compatibility. Use "node-24"/"node-26" instead. "experimental-node-24", "experimental-node-26", "bun", From 0fa17a7924b9be99e52281eba597271631c300ba Mon Sep 17 00:00:00 2001 From: Chris Arderne Date: Wed, 22 Jul 2026 13:28:52 +0100 Subject: [PATCH 2/4] format --- packages/core/src/v3/build/runtime.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/core/src/v3/build/runtime.ts b/packages/core/src/v3/build/runtime.ts index 21d56d258be..14d4ca46a5b 100644 --- a/packages/core/src/v3/build/runtime.ts +++ b/packages/core/src/v3/build/runtime.ts @@ -8,9 +8,7 @@ export const DEFAULT_RUNTIME = "node" satisfies BuildRuntime; export type DeprecatedConfigRuntime = "experimental-node-24" | "experimental-node-26"; -export function isDeprecatedConfigRuntime( - runtime: unknown -): runtime is DeprecatedConfigRuntime { +export function isDeprecatedConfigRuntime(runtime: unknown): runtime is DeprecatedConfigRuntime { return runtime === "experimental-node-24" || runtime === "experimental-node-26"; } From 645d23474002be1405606ad8251106fe530fd781 Mon Sep 17 00:00:00 2001 From: Chris Arderne Date: Wed, 22 Jul 2026 13:37:06 +0100 Subject: [PATCH 3/4] docs: drop deprecation note for unpublicised experimental runtimes --- docs/snippets/node-versions.mdx | 5 ----- 1 file changed, 5 deletions(-) diff --git a/docs/snippets/node-versions.mdx b/docs/snippets/node-versions.mdx index f71c2874f7d..d11f50f3fc9 100644 --- a/docs/snippets/node-versions.mdx +++ b/docs/snippets/node-versions.mdx @@ -17,8 +17,3 @@ export default defineConfig({ project: "", }); ``` - - - The `experimental-node-24` and `experimental-node-26` runtime names are deprecated. Use `node-24` - and `node-26` instead. - From f3ed7c2be35d3a1c8a9c10e7ff40b95acdc991dc Mon Sep 17 00:00:00 2001 From: Chris Arderne Date: Wed, 22 Jul 2026 13:40:54 +0100 Subject: [PATCH 4/4] fix(core): keep deprecated experimental runtime helper aliases Preserve isExperimentalConfigRuntime and ExperimentalConfigRuntime as deprecated re-exports so the rename stays backwards compatible. --- packages/core/src/v3/build/runtime.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/core/src/v3/build/runtime.ts b/packages/core/src/v3/build/runtime.ts index 14d4ca46a5b..aa4617c9df5 100644 --- a/packages/core/src/v3/build/runtime.ts +++ b/packages/core/src/v3/build/runtime.ts @@ -22,6 +22,12 @@ export function deprecatedRuntimeReplacement(runtime: DeprecatedConfigRuntime): } } +/** @deprecated Renamed to {@link DeprecatedConfigRuntime}. */ +export type ExperimentalConfigRuntime = DeprecatedConfigRuntime; + +/** @deprecated Renamed to {@link isDeprecatedConfigRuntime}. */ +export const isExperimentalConfigRuntime = isDeprecatedConfigRuntime; + export function resolveBuildRuntime(runtime: unknown): BuildRuntime { const parsedRuntime = ConfigRuntime.safeParse(runtime);