---
title: "Deno Deploy終了と移行手順：Cloudflare WorkersへのコードとKV・cronの移し方【2026年10月時点】"
url: "https://www.issoh.co.jp/tech/details/18318/"
published: 2026-10-13
updated: 2026-10-13
categories: ["インフラ・クラウド"]
publisher: "株式会社一創"
---

# Deno Deploy終了と移行手順：Cloudflare WorkersへのコードとKV・cronの移し方【2026年10月時点】

Deno Deployは、2026年10月9日の発表から6か月で運用を終えます。DenoのチームがCloudflareに合流するためで、移行先として案内されているのはCloudflare Workersです。この記事では、終了までの日程と未公表の点を公式発表で確かめたうえで、移行先をWorkers・Node.js・Bun・Denoの自前運用で比べます。後半は、`Deno.serve`のコードをWorkersへ書き換える手順、Fresh 2の設定、Deno KVのデータの書き出しと投入、`Deno.cron`のCron Triggers化を、コピーして使えるコードで示します。

## まとめ：Deno Deployは2027年4月ごろ終了しKVのデータ移送が最大の作業

Deno Deployの停止は、発表日から数えて2027年4月ごろです。正確な最終日はまだ公表されていません。Denoのランタイム自体も、1年間の保守のあとで開発が止まります。

移行先は、ほとんどの案件でCloudflare Workersが第一候補になります。Web標準の`Request`と`Response`で書かれたコードは、入口を`export default { fetch }`に変えるだけで動く部分が多いからです。手間がかかるのはコードではなくデータです。新しいDeno DeployのKVは外部から接続できないため、アプリの中に書き出し用のルートを足すか、S3への継続バックアップから取り出す必要があります。

Deno KVを使っているなら、今月中に書き出しの経路を作ってください。メモリ128MBを超える処理や子プロセスを使う処理があるなら、WorkersではなくNode.jsのコンテナへ移します。

## 2026年10月9日の発表で決まったDeno Deploy・ランタイム・JSRの今後

発表は[Denoの公式ブログ「Deno is joining Cloudflare」](https://deno.com/blog/cloudflare)と、[Cloudflare側の同名の記事](https://blog.cloudflare.com/deno-joins-cloudflare/)の2本です。Deno Deployの扱いが書かれているのはDeno側の記事だけです。

### Deno Deployは発表から6か月で停止し最終日の日付は未公表という現状

Deno側の記事には「Deno Deploy will continue operating for six months before shutting down.」とあります。期間で書かれていて、日付の記載はありません。10月9日から6か月を数えると2027年4月上旬です。

有料プランの利用者には、Cloudflare Workersへの移行支援が提供されます。支援の中身や申し込み方法は、10月13日時点でまだ出ていません。無料プランの利用者は自力で移す前提で計画を立てるのが安全です。

### Denoランタイムは1年間の月次保守後に開発終了しJSRは運用を継続

ランタイムは今後1年間、月次のリリースでバグ修正とセキュリティ修正が続きます。その後、Denoチームとしての開発は終了です。コードはオープンソースのまま残り、引き継ぐ開発者を歓迎するとしています。

パッケージレジストリのJSRは止まりません。基盤はCloudflareへ移り、運用は続く予定です。`jsr:`で読み込んでいるパッケージは、移行後もnpm互換の形で取得できます。V8のRustバインディングであるrusty\_v8も保守が続き、Cloudflareのランタイムworkerdへの統合を目指すと書かれています。

### Deploy Classicの2026年7月停止と現行Deno Deployの違い

Deno Deployには2つの世代があります。[Deno Deployの公式ドキュメント](https://docs.deno.com/deploy/)によると、旧版のDeploy Classic（dash.deno.com）とsubhosting v1 APIは2026年7月20日に停止済みです。今回終了が決まったのは、その移行先だった現行版（console.deno.com）です。

同じドキュメントの比較表では、現行版はKVとcronに対応する一方、キュー（`kv.enqueue`）は非対応です。現行版で動いているアプリは`kv.enqueue`を使えないため、Deno Deploy固有の機能として移す対象はKVとcronの2つに絞れます。

## Deno Deployの移行先をWorkers・Node.js・Bun・自前運用で比較

移行先の候補は4つです。保守の見通しとコードの書き換え量の両方で比べます。

### 移行先4択の比較表と2027年10月以降の保守期間から見た選び方

| 移行先                | 書き換え量             | KVの移し先             | 2027年10月以降      | 向く案件             |
| ------------------ | ----------------- | ------------------ | --------------- | ---------------- |
| Cloudflare Workers | 入口とDeno名前空間API    | KV・Durable Objects | Cloudflareが継続   | API・SSR・Freshアプリ |
| Node.js（コンテナ）      | Deno名前空間APIと依存の解決 | Redis・PostgreSQLなど | Node.jsの保守周期どおり | 重い処理・子プロセス       |
| Bun（コンテナ）          | Node.jsとほぼ同じ      | Redis・SQLiteなど     | Bunの開発元次第       | 起動速度を重視する案件      |
| Deno自前運用           | ほぼ不要              | セルフホストのdenokv      | 保守終了・自己責任       | 移行までのつなぎ         |

実務ではまずWorkersを検討し、128MBのメモリ上限などの制約に当たる処理だけをNode.jsへ回す、という順番で十分です。BunのNode.js互換の範囲は[Bun 1.4のNode.js互換の実測範囲](https://www.issoh.co.jp/tech/details/16888/)で整理しています。

### Cloudflare Workersの無料枠10ミリ秒とPaidプラン月5ドルの制約

[Workersの制限一覧](https://developers.cloudflare.com/workers/platform/limits/)では、無料のWorkers FreeはHTTPリクエストあたりのCPU時間が10ミリ秒です。Workers Paidは既定30秒、設定で最大5分まで延ばせます。メモリはどちらも1 isolateあたり128MB、Workerのサイズは非圧縮で64MiBが上限です。

料金は[Workersの料金ページ](https://developers.cloudflare.com/workers/platform/pricing/)のとおり、Paidが月5ドルからで、月1,000万リクエストとCPU時間3,000万ミリ秒を含みます。Freeは1日10万リクエストまでです。業務で使うAPIはFreeの10ミリ秒に収まらないことが多いので、Paidを前提に見積もります。Workers全体の料金の考え方は[Cloudflare Workersの対応言語・無料枠・料金のまとめ](https://www.issoh.co.jp/tech/details/6760/)にあります。

### Denoの自前運用は修正が止まる2027年までのつなぎにとどめる理由

Denoを`deno compile`やDockerで自社のサーバーへ移せば、コードはほぼそのまま動きます。ただし約1年後に公式のセキュリティ修正が止まります。インターネットに公開するサーバーで、修正の出ないランタイムを使い続けるのは避けるべきです。

自前運用を選ぶのは、Workersへの書き換えが期限に間に合わない場合だけにします。その場合も、2027年10月ごろまでに2回目の移行を終える計画を最初から組んでおきます。

## Deno.serveをWorkersのfetchハンドラーとHonoへ書き換える手順

Deno Deployのコードは、Web標準のAPIで書かれた部分とDeno固有のAPIを呼ぶ部分に分かれます。前者はそのまま使え、書き換えるのは後者です。

### Deno.serveをexport default fetchへ移す設定と最小コード

移行前のDeno Deployのコードが次のような形だとします。

```
// main.ts（Deno Deploy）
Deno.serve((req) => {
  const url = new URL(req.url);
  if (url.pathname === "/health") return new Response("ok");
  return Response.json({ greeting: Deno.env.get("GREETING") });
});
```

Workersでは、`fetch`メソッドを持つオブジェクトを`export default`します。環境変数は`Deno.env`ではなく、第2引数の`env`から読みます。

```
// src/index.ts（Cloudflare Workers）
export interface Env {
  GREETING: string;
}

export default {
  async fetch(req: Request, env: Env): Promise<Response> {
    const url = new URL(req.url);
    if (url.pathname === "/health") return new Response("ok");
    return Response.json({ greeting: env.GREETING });
  },
} satisfies ExportedHandler<Env>;
```

設定ファイルの`wrangler.jsonc`は次のとおりです。

```
{
  "name": "my-app",
  "main": "src/index.ts",
  "compatibility_date": "2026-10-01",
  "vars": { "GREETING": "hello" }
}
```

[WorkersのNode.js互換のドキュメント](https://developers.cloudflare.com/workers/runtime-apis/nodejs/)によると、`compatibility_date`が2026-08-04以降なら`nodejs_compat`は既定で有効です。`npm:`で読み込んでいたパッケージの多くは、`package.json`に移せば動きます。ただし`child_process`は読み込めるだけの空の実装で、実行はできません。

HonoでDeno Deploy上に書いていたなら、作業はさらに少なくなります。`Deno.serve(app.fetch)`を`export default app`に変え、`Deno.env`を[Honoの公式手順](https://hono.dev/docs/getting-started/cloudflare-workers)にある`c.env`へ置き換えます。

### Deno.env・Deno.openKv・Deno.cronの置き換え先一覧

| Deno Deployでの書き方           | Workersでの置き換え先             |
| -------------------------- | -------------------------- |
| `Deno.serve(handler)`      | `export default { fetch }` |
| `Deno.env.get("X")`        | `env.X`（`vars`・シークレット）     |
| `Deno.openKv()`            | KV・Durable Objects         |
| `Deno.cron(...)`           | `crons`設定と`scheduled`ハンドラー |
| `Deno.readTextFile()`の読み込み | 静的アセットかビルド時の埋め込み           |
| `jsr:@std/...`の読み込み        | `npx jsr add`でnpm互換として追加   |

置き換え先の候補を洗い出すには、`grep -rn "Deno\." src/`でDeno名前空間の呼び出しを全件拾うのが早道です。件数が見えれば、移行の工数もほぼ決まります。

### Fresh 2をCloudflareのViteプラグインでWorkersへ載せる設定

Fresh 2はビルドにViteを使うため、Workers向けのプラグインを足すだけで載せられます。[Fresh公式のCloudflare Workers向け手順](https://usefresh.dev/docs/deployment/cloudflare-workers)の内容は次のとおりです。

```
deno install --allow-scripts npm:@cloudflare/vite-plugin npm:wrangler
```

```
// vite.config.ts
import { defineConfig } from "vite";
import { fresh } from "@fresh/plugin-vite";
import { cloudflare } from "@cloudflare/vite-plugin";

export default defineConfig({
  plugins: [fresh(), cloudflare()],
});
```

```
// server.js（Workersの入口）
import server from "./_fresh/server.js";

export default {
  fetch: server.fetch,
};
```

`wrangler.jsonc`の`main`は`./server.js`を指すようにします。注意点は、ルートのハンドラーで`Deno.openKv()`などを呼んでいる箇所です。Freshの部分は動いても、その呼び出しはWorkersで失敗するので、前の表に沿って置き換えます。Fresh 2の構成は[Deno Freshとアイランドアーキテクチャの解説](https://www.issoh.co.jp/tech/details/3619/)を、Vite上で同じ考え方を取るHonoXは[HonoXの特徴と採用判断](https://www.issoh.co.jp/tech/details/3614/)を参照してください。

## Deno KVのデータを書き出しWorkers KVとDurable Objectsへ移送

移行で最も時間がかかるのはこの章の作業です。データの量にかかわらず、書き出しの経路を先に作っておきます。

### 新Deno DeployではKV Connectで外から読めない制約と書き出し用ルート

[Node.jsからKVを使う方法のドキュメント](https://docs.deno.com/deploy/kv/node/)には、外部から接続するKV Connectは「新しいDeno DeployのKVでは提供していない」とあります。Classic時代のように`@deno/kv`で手元から読み出すことはできません。

確実なのは、稼働中のアプリに書き出し専用のルートを一時的に足す方法です。トークンで保護し、カーソルで1,000件ずつ返します。

```
// export_kv.ts（Deno Deployのアプリに一時的に追加する）
const kv = await Deno.openKv();
const TOKEN = Deno.env.get("EXPORT_TOKEN");

export async function exportKv(req: Request): Promise<Response> {
  if (!TOKEN || req.headers.get("authorization") !== `Bearer ${TOKEN}`) {
    return new Response("forbidden", { status: 403 });
  }
  const cursor = new URL(req.url).searchParams.get("cursor") || undefined;
  const iter = kv.list({ prefix: [] }, { limit: 1000, cursor });
  const rows: string[] = [];
  for await (const e of iter) {
    rows.push(JSON.stringify({ key: e.key, value: e.value }));
  }
  // 0件になったら空のカーソルを返して終了の合図にする
  return new Response(rows.join("\n") + "\n", {
    headers: {
      "content-type": "application/x-ndjson",
      "x-next-cursor": rows.length ? iter.cursor : "",
    },
  });
}
```

手元からは、カーソルが空になるまで繰り返し取得します。

```
cursor=""
: > kv_export.ndjson
while :; do
  curl -s -D headers.txt -G -H "Authorization: Bearer $EXPORT_TOKEN" \
    --data-urlencode "cursor=$cursor" "$APP_URL/__export_kv" >> kv_export.ndjson
  cursor=$(grep -i '^x-next-cursor:' headers.txt | cut -d' ' -f2 | tr -d '\r')
  [ -z "$cursor" ] && break
done
```

この例は、キーと値が文字列・数値・真偽値・プレーンなオブジェクトだけの前提です。`bigint`は`JSON.stringify`で例外になり、`Uint8Array`や`Deno.KvU64`は形が崩れます。使っている型を先に確かめ、該当するなら変換処理を足してください。書き出しが終わったらルートとトークンは削除します。

### S3継続バックアップとdenokvのpitrコマンドで手元に複製する方法

もう1つの経路が、ダッシュボードから設定する継続バックアップです。[KVのバックアップのドキュメント](https://docs.deno.com/deploy/kv/backup/)のとおり、KVタブの「Backup」でS3またはGoogle Cloud Storageのバケットを指定すると、状態が「Active」になって書き込みが続きます。

バケットに溜まったデータは、[denokvのリポジトリ](https://github.com/denoland/denokv)にあるツールで手元のSQLiteへ同期できます。

```
denokv --sqlite-path ./denokv.sqlite pitr sync --s3-bucket your-bucket --s3-prefix <バックアップのプレフィックス>/
denokv --sqlite-path ./denokv.sqlite pitr list
```

同期したファイルは`denokv serve`で立ち上げれば`@deno/kv`から読めるので、前節と同じ書き出し処理を手元で回せます。本番のアプリに手を入れたくない場合や、移行当日まで差分を取り続けたい場合はこちらが向いています。

### 結果整合のWorkers KVと強い整合のDurable Objectsへの振り分け基準

移し先は2つに分かれます。[Workers KVの仕組みのページ](https://developers.cloudflare.com/kv/concepts/how-kv-works/)によると、Workers KVは結果整合で、他の拠点に反映されるまで60秒以上かかることがあり、アトミックな操作には向かないとされています。[書き込みのドキュメント](https://developers.cloudflare.com/kv/api/write-key-value-pairs/)では、同じキーへの書き込みは1秒に1回までです。

判断の基準は、Deno KVで`kv.atomic()`を使っていたかどうかです。在庫や残高のように`check`で版を確かめて更新していたデータは、[SQLiteを使うDurable Objects](https://developers.cloudflare.com/durable-objects/api/sqlite-storage-api/)へ移します。`transactionSync`でまとめて更新でき、SQLも使える構成です。設定値やキャッシュのように読む回数が多く更新の少ないデータは、Workers KVで足ります。

キーの並び順にも注意が必要です。Deno KVのキーは`["post", 9]`のような型付きの配列で、数値は数値の大小で並ぶ仕組みです。Workers KVのキーは文字列なので、`post:9`と`post:10`は文字列として比べられ、順序が入れ替わります。範囲指定で一覧を取っていた処理は、ゼロ埋めするか、Durable ObjectsのSQLで並べ直します。

### wrangler kv bulk putで1万件ずつ投入するJSON変換スクリプト

Workers KVへ入れる分は、書き出したNDJSONを一括投入用のJSONに変えます。一括投入は1回1万件までで、キーは512バイトまでです。

```
// to_bulk.mjs（Node.jsで実行）
import { readFileSync, writeFileSync } from "node:fs";

const lines = readFileSync("kv_export.ndjson", "utf8").split("\n").filter(Boolean);
const pairs = lines.map((line) => {
  const { key, value } = JSON.parse(line);
  return { key: key.join(":"), value: JSON.stringify(value) };
});
const tooLong = pairs.filter((p) => Buffer.byteLength(p.key) > 512);
if (tooLong.length) throw new Error(`512バイト超のキーが${tooLong.length}件あります`);

for (let i = 0; i < pairs.length; i += 10000) {
  writeFileSync(`bulk_${i / 10000}.json`, JSON.stringify(pairs.slice(i, i + 10000)));
}
```

```
npx wrangler kv namespace create APP_KV
npx wrangler kv bulk put bulk_0.json --binding=APP_KV --remote
```

コマンドの一覧は[WranglerのKVコマンドのリファレンス](https://developers.cloudflare.com/kv/reference/kv-commands/)にあります。投入後は件数と、いくつかのキーの値を元のデータと突き合わせてから切り替えます。

## Deno.cronの定期処理をCron Triggersのscheduledへ写す設定

[Deno Deployのcronのドキュメント](https://docs.deno.com/deploy/reference/cron/)と[WorkersのCron Triggersのドキュメント](https://developers.cloudflare.com/workers/configuration/cron-triggers/)は、どちらも時刻をUTCで扱います。cron式は書き換えずにそのまま移せます。

### 複数のDeno.cronを1つのscheduledハンドラーで振り分ける実装例

Deno Deployで、日本時間の午前3時と15分ごとの2つの処理を登録していたとします。

```
Deno.cron("cleanup", "0 18 * * *", () => cleanup());
Deno.cron("sync", "*/15 * * * *", () => syncOrders());
```

Workersでは、`wrangler.jsonc`にcron式を並べ、1つの`scheduled`ハンドラーで`controller.cron`を見て分岐します。

```
// wrangler.jsonc に追加
"triggers": { "crons": ["0 18 * * *", "*/15 * * * *"] }

// src/index.ts
export default {
  async fetch(req: Request, env: Env) { /* 省略 */ return new Response("ok"); },
  async scheduled(controller: ScheduledController, env: Env, ctx: ExecutionContext) {
    if (controller.cron === "0 18 * * *") ctx.waitUntil(cleanup(env));
    if (controller.cron === "*/15 * * * *") ctx.waitUntil(syncOrders(env));
  },
} satisfies ExportedHandler<Env>;
```

違いは2点です。`Deno.cron`の`backoffSchedule`で指定していた再試行は、Cron Triggersの設定にありません。失敗時に再試行したい処理は[Cloudflare Queues](https://developers.cloudflare.com/queues/)へ投げ、キュー側の再試行に任せます。もう1点は登録数で、Cron Triggersはアカウントあたり無料で5件、Paidで250件までです。

## Deno Deploy移行を今すぐ始める案件と年明けでよい案件の線引き

期限まで約6か月あっても、すべての案件が同じ緊急度ではありません。

### Deno KVの利用・独自ドメイン・Fresh固有処理の有無で着手時期を決める基準

次のどれかに当てはまる案件は、今月中に着手します。

- Deno KVに業務データがある（書き出し経路の用意と、Workers KVかDurable Objectsかの設計が要る）
- `kv.atomic()`で整合性を守っている処理がある（Durable Objectsへの作り直しになる）
- 独自ドメインで公開している（DNSと証明書の切り替え、停止期間の調整が要る）
- Freshのルートハンドラーから`Deno.*`のAPIを多く呼んでいる

一方、KVを使わずHonoや`Deno.serve`で書いた外部API中継のようなアプリは、書き換えが数時間で済みます。年明けに着手しても間に合いますが、2027年3月には切り替えを終える計画にしておきます。停止日が公表されていない以上、4月に入ってからの作業は避けるべきです。

### メモリ128MB・子プロセス・長時間処理が要件ならWorkersを見送る判断

次の処理を含むアプリは、Workersへ移しません。

- 1回の処理でメモリを128MB以上使う（大きなCSVや画像の変換など）
- 外部コマンドを子プロセスで呼ぶ（`child_process`は動かない）
- 1リクエストのCPU時間が5分を超えうる

これらはNode.jsのコンテナへ移し、軽いAPIだけをWorkersに置く分割が現実的です。Denoの権限設計やLTSを前提に組んだ構成をどこまで残すかは、[DenoとFreshの開発環境・LTS選定の解説](https://www.issoh.co.jp/tech/details/4646/)と照らして決めます。移行先の選定からデータ移行、切り替え当日の手順までをまとめて計画したい場合は、[システムマイグレーション・リプレイス](https://www.issoh.co.jp/service/system/migration/)で対応範囲を確認できます。

## Deno Deployの終了日・移行支援・ランタイムについてよくある質問

2026年10月13日時点の公式情報をもとに答えます。

### Deno Deployはいつ終了しますか？

Denoの公式ブログには「6か月運用したあとで停止する」とだけ書かれており、日付は示されていません。2026年10月9日の発表から数えると2027年4月上旬になります。停止日が後から公表される可能性はありますが、それを待たずに2027年3月までに切り替えを終える計画が安全です。最新の告知はDeno Deployのダッシュボードと公式ブログで確認してください。

### Cloudflareの移行支援は誰が受けられますか？

公式ブログでは、移行支援の対象は「Cloudflare Workersへ移る有料顧客」とされています。無料プランの利用者への支援は書かれていません。支援の具体的な内容や申し込み方法は、10月13日時点で公表されていません。有料プランを契約している場合でも、Deno KVの書き出しのようにアプリの中身に関わる作業は自社側で進める前提で準備しておくのが確実です。

### Denoランタイムはもう使わないほうがよいですか？

すぐに使えなくなるわけではありません。今後1年間は月次でバグ修正とセキュリティ修正が出ます。ただし、その後の開発はDenoチームとしては終わるため、新規のシステムをDenoで作るのは避けるのが無難です。CLIツールや社内スクリプトのように影響範囲が小さい用途は、1年の間にNode.jsやBunへ移す計画を立てれば足ります。

### JSRに公開したパッケージはどうなりますか？

JSRは運用を続けると明記されています。基盤がCloudflareへ移るだけで、公開済みのパッケージや`jsr:`での読み込みは引き続き利用可能です。Workersへ移したアプリからJSRのパッケージを使う場合は、`npx jsr add`でnpm互換の形として追加します。

### Deno KVのデータをClassicのように@deno/kvで読み出せますか？

現行のDeno DeployのKVは、外部からのKV Connectに対応していません。`@deno/kv`で直接読み出す方法はClassic時代のデータベース向けです。現行版では、アプリに書き出し用のルートを足すか、ダッシュボードでS3かGoogle Cloud Storageへの継続バックアップを設定し、denokvツールで手元に同期してから読み出します。

## 関連記事

- [Deno Freshとは｜Preactとアイランドアーキテクチャの軽量Webフレームワーク](https://www.issoh.co.jp/tech/details/3619/)：Workersへ移すFresh 2アプリの構成を確かめるときに。
- [DenoとFreshの開発環境セットアップ｜インストール・権限設計・LTS選定](https://www.issoh.co.jp/tech/details/4646/)：移行までの間、手元のDeno環境を保つときに。
- [Cloudflare Workersとは？対応言語・無料枠・使い方・料金を最新版で総まとめ](https://www.issoh.co.jp/tech/details/6760/)：移行先のWorkersの料金と無料枠の確認に。
- [Bun 1.4とは？Rust実装への移行とNode.js互換の実測範囲を実装目線で解説](https://www.issoh.co.jp/tech/details/16888/)：WorkersでなくBunへ移す場合の互換範囲の確認に。
- [Supabase Edge Functionsとは：Deno実行環境とデプロイ・シークレット・課金単位](https://www.issoh.co.jp/tech/details/17061/)：Denoで書いた関数を別の基盤で動かす選択肢として。

---

出典: [Deno Deploy終了と移行手順：Cloudflare WorkersへのコードとKV・cronの移し方【2026年10月時点】](<https://www.issoh.co.jp/tech/details/18318/>)（株式会社一創）
