Skip to content
Developer tooling

Deno Deploy shuts down in six months: where to move your apps, and what to rewrite

Deno's team is joining Cloudflare and Deploy closes in six months. What ends, what stays, and how to move an app to Workers or Node.

K8 min read
Apps being packed up and moved to a new home is exactly what the article is about.

On 9 October 2026 Cloudflare announced that the Deno team is joining it, and the coverage since has settled what that means in practice. Development of the standalone Deno runtime stops after a year of monthly maintenance and security releases. Deno Deploy shuts down in six months. JSR, the package registry, carries on under Cloudflare (The New Stack, Runtime Wire).

If you run anything on Deno Deploy, you now have a deadline. This article sorts out what ends and what stays, helps you pick where to move by what your code actually uses, and shows the rewrite for the two likely destinations: Cloudflare Workers and Node.js. It ends with what self-hosted Workers might look like, since that is the project Deno's founders are moving to.

Your Deno appDeno DeployclosingCloudflare WorkersNode.js 24 or 26your serversworkerd + celldself-hostedJSRmoves to Cloudflaretodaysame fetch modelown infrastructurelater, maybepackages
Two destinations work today; self-hosted Workers is a plan, not a product.

What ends and what stays

The announcements cover some parts of Deno in detail and say nothing about others. Treat a blank in this table as "not announced", not as "safe".

PartWhat happensSource
Deno runtime (CLI)Monthly bug-fix and security releases for one more year, then development stops. Stays MIT-licensed.The New Stack
Deno DeployRuns for six more months, then shuts down. Paying customers get help moving to Workers.Runtime Wire
JSRKeeps running; its infrastructure moves to Cloudflare.Runtime Wire
rusty_v8Still supported, with work towards using it in workerd.Runtime Wire
celldMerged into workerd to make self-hosting Workers a supported option.Cloudflare
Deno KV, FreshNot addressed in the coverage.—
Deno Deploy has the shortest runwayMonths of support left, counted from October 2026
Deno Deploy6  monthsDeno runtime fixes12  monthsNode.js 24 LTS18  monthsNode.js 26 LTS30  months

Source: The New Stack (Deno); nodejs.org (Node 26 end of life April 2029); ecorpit.com (Node 24 end of life April 2028)

Deno Deploy has the shortest runway
Months left
Deno Deploy6  months
Deno runtime fixes12  months
Node.js 24 LTS18  months
Node.js 26 LTS30  months

Six months from 9 October puts the Deploy shutdown around April 2027. Deno's own announcement on deno.com/blog is the place to confirm the exact date, and to check on Deno KV and Fresh before you plan around them.

Why the runtime is ending

Deno shipped in 2018 as Ryan Dahl's second attempt at a server-side JavaScript runtime, with TypeScript, a permission model and web-standard APIs built in. Deno 2, released in October 2024, was mostly about Node.js compatibility (Wikipedia)). That is the problem Dahl points to now: Node adopted native TypeScript, permission controls and web APIs, and the closer Deno got to Node, the more it was maintaining a second implementation of the same thing (The New Stack).

Node now ships most of what made Deno different, so the runtime had less and less of its own to sell.

The contrast with Bun is worth noting. Anthropic bought Bun in December 2025 and committed to keeping it open source; Deno's runtime gets a year of fixes instead (The New Stack). Both runtimes now belong to companies whose main business is something else, and that is a fair input when you choose what to build on next.

Pick a destination by what your code uses

Most Deno Deploy apps are a Deno.serve handler plus a few environment variables, and those move easily to either destination. The decision is made by the parts that are not standard web APIs.

If your app usesMove toWhy
Deno.serve, fetch, Web CryptoWorkers or NodeSame Request/Response model on both
Deno KV with atomic()Workers + Durable Objects, or Node + a databaseWorkers KV has no atomic operations
Files, subprocessesNodenode:child_process is a non-functional stub on Workers
Your own servers, no vendorNode nowSelf-hosted Workers is not ready yet

The Workers limits come from Cloudflare's Node.js compatibility page, which lists node:vm and node:child_process as stubs that import but do not work.

Moving a Deploy app to Cloudflare Workers

Workers and Deno Deploy share the same model: a function that takes a Request and returns a Response. The rewrite is mostly the entry point and where configuration comes from.

Swap Deno.serve for a fetch handler

A Worker exports an object with a fetch method. Environment variables arrive as the env argument instead of through Deno.env.

src/main.tsDiff
- Deno.serve((req) => {-   const url = new URL(req.url);-   return new Response(`Hello ${Deno.env.get("NAME")} from ${url.pathname}`);- });+ export default {+   async fetch(req: Request, env: { NAME: string }): Promise<Response> {+     const url = new URL(req.url);+     return new Response(`Hello ${env.NAME} from ${url.pathname}`);+   },+ };

Configure it with Wrangler

Set compatibility_date to 2026-08-04 or later and Node.js compatibility is on by default, so code that imports node:buffer or node:crypto keeps working. Earlier dates need the nodejs_compat flag (Cloudflare docs).

wrangler.jsoncJSON
{  "name": "my-app",  "main": "src/main.ts",  "compatibility_date": "2026-08-04",  "vars": { "NAME": "k13" }}
Terminal
$ npx wrangler dev$ npx wrangler deploy

Put secrets in with npx wrangler secret put, not in vars, which is plain configuration checked into your repository.

Deno KV does not map to Workers KV

The names match; the guarantees do not. Deno KV gives you strongly consistent reads by default and transactions through kv.atomic() with .check() on a versionstamp (Deno docs). Workers KV is eventually consistent: a write can take 60 seconds or more to show up in other locations, and Cloudflare says it is not suited to atomic operations (Cloudflare docs).

Read-heavy data that tolerates a minute of staleness, such as feature flags or cached pages, is fine on Workers KV.

Moving to Node.js instead

If you want to run on your own servers, Node is the shortest path, and the gap is much smaller than it was when Deno launched. Node runs .ts files directly: type stripping is on by default from Node 22.18.0 and 23.6.0, and stable from 24.12.0 and 25.2.0 (Node.js docs).

Node only removes type annotations; it does not transform code. That is where Deno code trips:

  • enum, namespace with runtime code, and constructor parameter properties throw ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX.
  • Imports need their file extension: ./db.ts, not ./db.
  • Type-only imports need the type keyword, or Node tries to load them at runtime.
  • --experimental-transform-types was removed in Node 26; use tsx if you depend on enums.

Turn on erasableSyntaxOnly and verbatimModuleSyntax in tsconfig.json and tsc will flag all of these before Node does.

DenoNode.js
Deno.serve(handler)node:http, or Hono with @hono/node-server
Deno.env.get("X")process.env.X
Deno.readTextFile(path)readFile(path, "utf8") from node:fs/promises
npm: specifierspackage.json dependencies
jsr: specifiersnpx jsr add @scope/pkg (JSR docs)
--allow-read, --allow-write--permission with --allow-fs-read, --allow-fs-write

Write the app once, run it anywhere

If you are not sure where you will end up, put the app behind a framework that runs on all three. Hono supports Workers, Deno, Bun and Node, and only the entry file changes.

src/app.tsTypeScript
import { Hono } from "hono"; export const app = new Hono(); app.get("/", (c) => c.text("ok"));app.get("/hello/:name", (c) => c.json({ hello: c.req.param("name") }));
src/worker.tsTypeScript
import { app } from "./app.ts"; export default app;
src/node.tsTypeScript
import { serve } from "@hono/node-server";import { app } from "./app.ts"; serve({ fetch: app.fetch, port: 3000 });
src/deno.tsTypeScript
import { app } from "./app.ts"; Deno.serve({ port: 8000 }, app.fetch);

Run the Node entry with node src/node.ts on Node 24, and keep the Deno entry working for the next year while you test. On Deno, hono comes from an import map entry in deno.json, such as "hono": "npm:hono" (Hono docs).

What self-hosted Workers might look like

The project Dahl and Bert Belder will lead at Cloudflare is making Workers something you can run on your own machines (Cloudflare). workerd, Cloudflare's open-source runtime, already runs Workers code, but its Durable Objects support is limited to a single instance: fine for local testing, unable to scale across machines (Technobezz). celld, which Deno released in August under Apache-2.0, is the missing layer.

ClientNode Aowns cell 7Node BstandbyCell 7V8 isolate + SQLiteObject storageS3, R2, GCSrequestrunsreplicates stateclaims ownershiprestores on failure
The bucket is the only shared component; there is no placement controller.

As described in Xenospectrum's write-up of celld v0.1.0, an app is split into named "cells", each a single-threaded V8 isolate with its own SQLite database. One node owns a cell at a time, and ownership is recorded in a shared object-storage bucket using conditional writes, with an epoch number to fence out an old owner after a failover. State is replicated to the bucket, so another node can restore a cell if its host dies. Every durable write waits for at least one bucket round trip.

Cloudflare has said more details will follow over the coming months. Until there is a merged, documented release, plan your move around Workers or Node, not around this.

What to do this week

  • List every app on Deno Deploy, with an owner and a target: Workers or Node.
  • Search each codebase for Deno.openKv and .atomic(). Those are the parts that need a real design, not a rename.
  • Search for Deno. calls and map each one with the table above.
  • Move the entry point behind Hono or a plain fetch handler, so the destination is a one-file change.
  • Pin your Deno version in CI for the year of maintenance releases, and set a reminder for when they stop.
  • Check deno.com/blog for the exact Deploy shutdown date and for news on Deno KV and Fresh.

If you only do one thing, do the KV search. Everything else is a rename; a lost atomic check is a bug you will find in production.

Found this useful? Share itXLinkedIn