JavaScript

WinterTCとは?WinterCGから移管したEcma TC55とECMA-429の要点

WinterTCは、Node.js・Deno・Bun・Cloudflare Workersといったサーバーサイド/エッジのJavaScriptランタイムに共通のAPIを決めるEcma Internationalの技術委員会(TC55)です。もともとW3CのコミュニティグループだったWinterCGが移った先で、2025年12月には最初の成果物である標準ECMA-429が公開されました。

まとめ:WinterTCの現在地(2026年7月時点)

  • WinterTCの正式名称はEcma International の TC55「Web-interoperable server runtimes」。JavaScript言語そのものを決めるTC39と同じ、Ecmaの技術委員会のひとつ。
  • 移管の向きは WinterCG(W3C)→ WinterTC(Ecma)。逆ではない。W3C側のWinterCGは 2025年4月3日に閉鎖済みで、wintercg.orgwintertc.org へリダイレクトする。
  • 最初の標準は ECMA-429「Minimum common web API」第1版(2025年12月公開)。ブラウザとサーバーの双方で使えるWeb標準APIの部分集合を、ランタイムが必ず備えるべき最低ラインとして定義したもの。
  • Runtime Keys(Ecma Technical Report)は、package.json の条件付きエクスポートなどで使う識別子のレジストリ。2026年1月20日時点で23件が登録済み。実行時のランタイム判定とは別物。
  • 名前が似ているWinterJSはWinterTCとは無関係の別プロジェクトで、2026年3月に非推奨化しリポジトリもアーカイブされた。

以下、それぞれの根拠と、実務で設計判断が変わる条件を見ていきます。

WinterTCの正体:Ecma TC55が決めること

Ecmaの公式ページで、TC55の名称は「Web-interoperable server runtimes」と定義されています。憲章は「複数のECMAScript実行環境、とりわけWebサーバーにおける相互運用性を高めるために有用な『最小共通API』の表面と、その適合性の検証可能な定義を、定め・洗練し・標準化すること」。加えて、既存のWeb標準がカバーしていないサーバー固有の機能について新しいAPIを標準化することも認めています。

体制は議長がIgaliaのAndreu Botella氏、幹事をEcma InternationalのAki Rose Braun氏とSamina Husain氏が務め、副議長は空席です(2026年7月時点)。TC39が言語仕様を決めるのに対し、TC55が扱うのは言語の外側にある実行環境のAPI群という分担になります。Array.prototype の挙動はTC39、fetch() がサーバー上で存在するかどうかはTC55、という切り分けだと考えると近いです。

移管を告知した各社の顔ぶれには、Node.js、Deno、Vercel、Fastly、Netlify、Shopifyが並びました。ECMA-429の編集者はCloudflareのJames M Snell氏です。普段は競合する主要ランタイムのベンダーが、コードから見えるAPI表面だけは揃えようとしている構図で、Cloudflare Workersの対応言語や無料枠と、Bunのインストールやコマンド体系がまるで違っていても、共通部分は保証されるという状態を目指しています。

WinterCGからWinterTCへ移った理由と、閉鎖後の参照先

Community Groupでは標準を発行できない制約

WinterCG(Web-interoperable Runtimes Community Group)は、2022年5月にW3Cのコミュニティグループとして発足しました。ただしW3Cのコミュニティグループは、勧告や標準を正式に発行する権限を持ちません。仕様のドラフトは書けても、それが「規格」になることはない。加えて扱う範囲がWeb由来ではないサーバー固有のAPIにも広がったため、2024年12月にEcmaへ移ることが決まり、2025年1月10日にW3C側とDeno、Igaliaがそろって告知しました。

旧版の本記事を含め、日本語の解説には「WinterTCからWinterCGへの移行」と向きを逆に書いたものが残っています。正しくは、標準を発行できる場所を求めてWinterCGがEcmaへ出ていき、そこでの名前がWinterTC(TC55)です。

2025年4月3日のWinterCG閉鎖と現在の参照先

W3CのWinterCGページには「This group was closed on 2025-04-03」と明記されており、グループの作業はすべてEcmaへ引き継がれています。ドメインも wintercg.orgwintertc.org へ301リダイレクトする状態です。

一方でGitHub組織は wintercg から WinterTC55 へ移っており、Runtime Keysの公開ページのように旧ドメイン配下のURLがまだ生きているものもあります。ブックマークやドキュメント内のリンクは、閉鎖したCGではなくTC55側の wintertc.orggithub.com/WinterTC55 に貼り直しておくのが無難です。

ECMA-429の収録範囲:必須APIと対象外

ECMA-429の正式名は「Minimum common web API」、第1版が2025年12月に公開されました。規格本文は自らを「2025年スナップショット」と位置づけ、W3CとWHATWGのWeb標準から選び出したAPIの部分集合を、ブラウザとサーバーの双方に共通する最低限の能力として定義しています。Introductionには年次刊行を目指す方針も明記されており、次の節目は2026年版スナップショットです。仕様のドラフトは公開リポジトリで更新が続いています(最終更新は2026年4月28日)。

globalThisに必須のインターフェース

  • DOM:AbortController / AbortSignal / Event / EventTarget
  • HTML:CustomEvent / ErrorEvent / MessageChannel / MessageEvent / MessagePort / PromiseRejectionEvent
  • WebIDL:DOMException
  • Fetch:Headers / Request / Response
  • XMLHttpRequest:FormData
  • File API:Blob / File
  • Compression:CompressionStream / DecompressionStream
  • Streams:ReadableStream系・WritableStream系・TransformStream系など計13種
  • Encoding:TextEncoder / TextDecoder / TextEncoderStream / TextDecoderStream
  • URL:URL / URLSearchParams
  • URL Pattern:URLPattern
  • Web Cryptography:Crypto / CryptoKey / SubtleCrypto
  • High Resolution Time:Performance
  • WebAssembly:Global / Instance / Memory / Module / Table / Tag / Exception / 各種Error

Web開発者にとって目新しいものはほとんどありません。裏を返せば、ブラウザで書き慣れたコードのうちどこまでがサーバー側でも保証されるのかが、初めて規格として固定されたということです。WebAssembly関連が丸ごと必須に入っている点は、WebAssemblyとJavaScriptの連携をエッジ環境で組む場合の前提として押さえておくと判断が早くなります。

必須のメソッド・プロパティと、規格が触れていない領域

インターフェースとは別に、globalThis 直下のメソッドとプロパティも列挙されています。HTML由来の atob() btoa() setTimeout() setInterval() clearTimeout() clearInterval() queueMicrotask() reportError() structuredClone() self navigator.userAgent、エラー系ハンドラの onerror onunhandledrejection onrejectionhandled、そしてFetch由来の fetch()、Console由来の console、Web Crypto由来の crypto、High Resolution Time由来の performance、WebAssemblyの compile() instantiate() validate() などです。

逆に、ファイルシステム、TCP接続、プロセス制御、子プロセス起動といったサーバーらしいAPIは第1版に含まれていません。Web Workersの対応も必須ではなく、「もしWorkerGlobalScopeに相当するグローバルスコープを持つなら、そこにもエラー系ハンドラを出すこと」という条件付きの規定にとどまります。ECMA-429に準拠していることは、ランタイム間でコードが完全に動くことを意味しません。あくまで最低ラインです。

互換性への配慮も明文化されています。既存アプリのコードとグローバル変数が衝突する事故を避けるため、規格が追加を求めるグローバルプロパティについては、Web標準側で readonly とされていても、準拠ランタイムは readonly を外して上書き・削除可能にしてよいとされています。

Node.jsだけに認められた例外規定

この規格でいちばん実務に効くのは、Node.jsの扱いを名指しで例外にしている箇所です。ECMA-429は原則としてグローバルオブジェクトが EventTarget であることを求め、error unhandledrejection rejectionhandled の各イベントをグローバルで発火させることを想定しています。しかしNode.jsのグローバルオブジェクトは EventTarget ではありません。

そこで規格は、レガシーな事情でそれが不可能な場合には同等の情報を提供する代替機構でイベントを通知すればよいとし、その種のランタイムは onerror 等のグローバルプロパティを持ってはならない(shall not support)と定めました。ErrorEventPromiseRejectionEvent の実装のほうは求められていません。Node.jsが process オブジェクト上で uncaughtException unhandledRejection rejectionHandled を発火させている現行の挙動が、そのまま規格の想定内に収まっている形です。

つまり、エラーハンドリングの共通化だけは今後も期待しないほうがいい。ランタイム横断のライブラリを書くなら、この一点は分岐を残す前提で設計するのが現実的です。

Runtime Keysの用途と、実行時のランタイム判定

Runtime Keysはビルド設定側の識別子

Runtime KeysはMinimum common web APIとは別のEcma Technical Reportで、レジストリの実体は runtime-keys.json、バージョン1.0.0・最終更新2026年1月20日時点の登録は23件です。仕様は用途を「プロジェクト設定ファイル、パッケージマニフェスト、条件付きエクスポート、ランタイム検出機構などを含むがそれに限らない、さまざまな文脈でECMAScriptランタイムを識別するための一貫した仕組み」と説明し、そのうえで「この仕様はランタイムキーの使い方を規定しない」と明言しています。レジストリ登録の条件として挙げられている実績も package.jsonexports フィールドでの使用例です。

登録済みキーは次の23件です(区分は本記事による整理で、レジストリ側に区分の定義はありません)。

  • 汎用ランタイム:node / deno / bun / kiesel / andromeda / rhino
  • エッジ・サーバーレス:workerd / edge-light / edge-routine / fastly / netlify / azion / arvancloud / lagon / convex / wasmer
  • アプリ・組込み:electron / react-native / moddable / quickjs / quickjs-ng / pythonmonkey
  • その他:react-server(React Server Componentsの実行条件として使われる)

新しいランタイムを登録したい場合は、runtime-keys.json にエントリを追加するプルリクエストを出します。審査はTC55参加者が行い、対象ランタイムに直接所属していない委員2名以上の承認を得たうえで、TC55の本会議(plenary)で正式承認されてからマージされる流れです。レポート自体は半期ごとに発行されます。

レポートには明確な免責が置かれています。掲載されているからといって、そのランタイムがECMA-429を含むEcma仕様に完全準拠していることを意味せず、いかなる推奨も意味しない。「Runtime Keysに載っている=WinterTC準拠」と読むのは誤りです。

実行時の判定はnavigator.userAgentで行う

実行中の環境が何かをコードから知る手段は、Runtime Keysではなく、ECMA-429が必須化した navigator.userAgent です。規格はこの値をRFC 7231のUser-Agent構文に従う文字列とし、バージョンを含まない単一のproductトークンに留めることを推奨していますが、あくまで推奨です。Node.jsの公式ドキュメントは「ランタイム名とメジャーバージョン番号からなるユーザーエージェントを返す」と明記し、例として Node.js/21 を挙げています。Denoも Deno/2.1.4 のように版番号を付けます。

したがって完全一致で比較すると、どの分岐にも入りません。/ より前を切り出すか、前方一致で判定します。

const ua = globalThis.navigator?.userAgent ?? "";
const runtime = ua.split("/")[0];   // "Node.js/26" なら "Node.js"

if (runtime === "Cloudflare-Workers") {
  // KVやDurable Objectsなど固有APIを使う分岐
} else if (runtime === "Deno" || runtime === "Node.js") {
  // ファイルシステムが使える前提の分岐
}

規格自身は、この値をアプリ側から「単一で完結した、不透明で構造を持たない値」として扱うべきだとも書いています。特定APIが必要なだけなら、ランタイム名で分岐するより typeof CompressionStream !== "undefined" のような機能検出のほうが壊れにくく、規格の意図にも沿います。navigator.userAgent による分岐は、ログ出力や、機能検出では区別できない実装固有の挙動を避けたいときに限るのが安全です。

WinterJSとの混同に注意:2026年に非推奨化した別プロジェクト

WinterCG/WinterTCを調べていると、ほぼ必ずWinterJSという名前が出てきます。これはWasmerが開発したJavaScriptサーバーで、Service Workerスクリプトを実行するランタイムです。名前とロゴの雰囲気が似ているため委員会の公式実装だと誤解されがちですが、WinterJS自身のREADMEが「WinterJSは名前に”Winter”を共有しているものの、WinterCGから公式に承認されたものではない」と明記しています。

そのうえで現状を書いておくと、wasmerio/winterjs リポジトリはアーカイブ済みです。2026年3月17日のREADME更新で「このプロジェクトはEdge.js JSランタイムを優先して非推奨になりました」という告知が入り、それが最終コミットになりました。公式サイトの winterjs.org もGitHubリポジトリへ転送されるだけになっています。移行先として案内されているEdge.jsは、Wasmerのサンドボックス上でNode.jsアプリをそのまま動かす方向の製品です。

2025年以前の記事はWinterJSを「WinterCGの成果が形になった高速ランタイム」として紹介しているものが多いままです。新規に採用を検討する対象ではありません。

標準化が進行中の3領域(2026年時点)

ECMA-429の次に何が来るかは、TC55のリポジトリを見ると輪郭が分かります。

  • Sockets API:ブラウザ以外のJavaScript環境でTCP接続を張るためのAPI。実装例としてNode.js向けのポリフィルとCloudflare WorkersのTCP Socketsが挙げられている。ECMA-429に含まれなかったネットワーク層を埋める位置づけ。
  • iter-streams:2026年1月に公開された、Web Streams APIを非同期イテレーション前提で設計し直すプロトタイプ。README自身が「本番環境で使うな」と明示する段階で、既存のReadableStreamを置き換える話が実装に降りてくるのはまだ先。
  • HTTPサーバーAPI:2026年2月にリポジトリだけが作られた状態で、公開されている中身はまだない。

Fetchの差分仕様やpackage.jsonの仕様提案はアーカイブされ、Fetchについては独自仕様を持たずWHATWG側へ変更を提案する方針に切り替わっています。委員会の重心が「Web標準を書き換える」から「Web標準の部分集合を規格として固定し、足りない部分だけ新規に足す」へ移った、と読めます。

なお、あるランタイムがECMA-429を満たしているかを機械的に判定する公式の適合性テストスイートは、まだ公開されていません。Web Platform Testsのうち最小共通APIに対応する範囲を選り分ける作業が進行中で、現時点で「準拠」を名乗る根拠は各ランタイムの自己申告にとどまります。

WinterTC準拠を判断基準にすべきでない場面

もっとも誤解されやすいのが、既存のNode.jsアプリを別ランタイムへ移す場面です。fschild_process のようなNode.js固有モジュールはECMA-429の対象外なので、移行先が準拠していても移植可否の材料になりません。ここで見るべきは規格ではなく、移行先が提供するNode.js互換レイヤの範囲です。

デプロイ先が単一に固定されている場合も同様で、Deno Freshで組んだアプリをDeno Deployだけで運用するなら、ランタイム固有APIを使ったほうが素直に書けます。性能や運用コストが選定の主軸なら、なおさら関係ありません。ECMA-429はAPIの有無を決めるだけで、実行速度・メモリ・コールドスタート・課金体系には一切関与しないからです。

WinterTCが効いてくるのは、ライブラリ作者がランタイムを問わず動くコードを配りたいときと、エッジとオリジンで同じロジックを共有したいとき。そこに当てはまらないなら、規格の動向は「知っておく」で十分です。

よくある質問

WinterTCとWinterCGは同じものですか

組織としては同じ流れにありますが、運営団体が違います。W3CのコミュニティグループだったWinterCGが2024年12月にEcma Internationalへの移管を決め、TC55として再出発したときの通称がWinterTCです。WinterCG側は2025年4月3日に正式に閉鎖されました。

WinterCGという名前はもう使わないほうがよいですか

現在進行中の作業を指す文脈では使わないほうが正確です。ドメインもGitHub組織もWinterTC側へ移っています。ただし2022年から2024年の経緯を説明するときは、当時の名称としてWinterCGを使って問題ありません。

ECMA-429はいつ公開されましたか

第1版が2025年12月に公開されました。規格名は「Minimum common web API」、内容は2025年時点のスナップショットと明記されています。委員会は年次での刊行を目指すとしており、以降のドラフトも公開リポジトリで更新が続いています。

どのランタイムがWinterTCに対応していますか

Runtime Keysのレジストリには2026年1月20日時点で23件が登録されており、Node.js、Deno、Bun、Cloudflare Workers(workerd)、Fastly、Netlify、Electronなどが含まれます。ただしレジストリへの登録は識別子の予約であって、ECMA-429への準拠を保証するものではないと明記されています。

WinterJSはWinterTCの公式ランタイムですか

違います。WasmerによるWinterJSは名前が似ているだけの独立したプロジェクトで、README自身がWinterCG非公認だと述べています。さらに2026年3月にEdge.jsへの移行を理由として非推奨化され、リポジトリもアーカイブされました。

関連記事

資料請求

RELATED POSTS 関連記事