ES2025(ECMAScript 2025)は、2025年6月25日にEcma Internationalの総会で承認されたJavaScriptの言語仕様で、ECMA-262の第16版です。Iterator Helpers、Setの集合演算メソッド、Promise.try、Import Attributes、正規表現の3機能、Float16Arrayが標準に入りました。
2026年6月には次の版のES2026(第17版)も承認されています。この記事はES2025に入った機能だけを扱い、各機能をNode.js 26.5.0で動かしたコードと出力、ブラウザとランタイムの対応版、TypeScriptで es2025 を指定できる版をまとめます。最新版のES2026までの流れはECMAScriptとは?JavaScriptとの違い・ES2026までの版とESMを解説にまとめています。
まとめ:ES2025の新機能と本番で使い始める条件
- Iterator Helpers:イテレーターに
map・filter・take・drop・toArrayなどが付き、配列を作らずに処理をつなげます。同期版だけで、非同期版はまだStage 2です。 - Setメソッド7種:
union・intersection・difference・symmetricDifference・isSubsetOf・isSupersetOf・isDisjointFrom。 - Promise.try:関数を同期的に実行し、同期の例外も拒否されたPromiseとして返します。
- Import AttributesとJSON Modules:
with { type: "json" }でJSONをimportします。旧構文のassertはNode.js 22.0.0とChrome 126で削除済みです。 - 正規表現:一部だけフラグを効かせる
(?i:...)、同名の名前付きグループ、RegExp.escape()。 - Float16Array:16ビット浮動小数点の型付き配列と
Math.f16round、DataViewのgetFloat16/setFloat16。
本番で全機能を使う下限は、Node.js 24以上、Chrome 136・Firefox 138・Safari 26以上、TypeScript 6.0以上です。Node.js 22では、後述の対応版表に載せた8機能のうち5つが動きません。正規表現のモディファイアを使わなければSafariの下限は18.4まで下がります。
ES2025の位置づけ:第16版の承認日とES2024・ES2026との境界
ECMAScriptは毎年6月にEcmaの総会で版を承認します。ECMA-262の公式ページでは、現行版が「17th edition, June 2026」(ES2026)になっており、ES2025は1つ前の版です。どの提案がどの年の版に入ったかは、TC39のfinished-proposals.mdの「Expected Publication Year」列で確認できます。
この列で2025となっている提案は次の10件です。
| ES2025の提案 | 追加されたもの |
|---|---|
| Sync Iterator helpers | Iterator.prototype.map など |
| New Set methods | Set.prototype.union など7種 |
| Promise.try | Promise.try() |
| Import Attributes | import … with { } |
| JSON Modules | type: “json” のimport |
| RegExp Modifiers | (?i:…) など |
| Duplicate named capture groups | | の左右で同じグループ名 |
| RegExp.escape | RegExp.escape() |
| Float16 on TypedArrays, DataView, Math.f16round | Float16Array など |
| Redeclarable global eval-introduced vars | evalで作ったグローバルvarの再宣言 |
最後の1件は、eval で作ったグローバル変数を後から let などで宣言し直せるようにした仕様の整理で、普段のコードを書き換える必要はありません。
前後の版と取り違えやすい機能もあります。ArrayBuffer.prototype.transfer、Promise.withResolvers、Object.groupBy、正規表現の v フラグはES2024です。Map.prototype.getOrInsert(Upsert)、Iterator.concat、Uint8Array のBase64変換、Math.sumPrecise、Error.isError、Array.fromAsync はES2026です。Intl.DurationFormat は国際化APIの仕様(ECMA-402)の2025年版で、ECMA-262のES2025とは別の文書に入っています。
Iterator Helpers:配列を作らない map・filter・take の遅延連結
これまで map や filter は配列のメソッドだったので、Mapのキーやジェネレーターを加工するには一度 [...iter] で配列に展開していました。ES2025ではイテレーターの共通の親 Iterator.prototype に11のメソッドが入り、展開せずにつなげます。
function* naturals() {
let n = 1;
while (true) yield n++;
}
// 無限に続くジェネレーターでも、必要な3件だけ計算する
const squares = naturals()
.filter((n) => n % 2 === 0)
.map((n) => n * n)
.take(3)
.toArray();
console.log(squares);
// [ 4, 16, 36 ]
const m = new Map([["a", 1], ["b", 2]]);
console.log(m.keys().map((k) => k.toUpperCase()).toArray());
// [ 'A', 'B' ]
追加されたのは、遅延評価で新しいイテレーターを返す map・filter・take・drop・flatMap と、最後まで消費して値を返す reduce・toArray・forEach・some・every・find の11メソッドに、静的メソッド Iterator.from() と、Iterator コンストラクター自体を加えたものです。配列なら従来どおり Array.prototype.map が使え、[1, 2, 3].values().map(...) と書いたときだけイテレーター版が動きます。
注意点は2つあります。1つ目は、イテレーターは1回しか回らないことです。
const it = [1, 2, 3].values().map((x) => x * 2);
console.log(it.toArray());
// [ 2, 4, 6 ]
console.log(it.toArray());
// []
Node.js 26.5.0では、2回目の toArray() が空配列を返しました。何度も使う結果は配列にして変数へ入れておきます。2つ目は、非同期版が無いことです。for await で読むストリームに map をつなぐ Async Iterator Helpers は別提案で、TC39の提案一覧ではStage 2にあります。asyncMap のような名前のメソッドはES2025に存在しません。
Setの集合演算メソッド:union・intersection・isDisjointFrom の7種
和集合や共通部分は、これまで [...a].filter((x) => b.has(x)) のように配列を経由して書いていました。ES2025で Set.prototype に7つのメソッドが入っています。
| メソッド | 戻り値 | a={1,2,3,4}、b={3,4,5}の結果 |
|---|---|---|
| a.union(b) | 新しいSet | {1,2,3,4,5} |
| a.intersection(b) | 新しいSet | {3,4} |
| a.difference(b) | 新しいSet | {1,2} |
| a.symmetricDifference(b) | 新しいSet | {1,2,5} |
| a.isSubsetOf(b) | 真偽値 | false |
| a.isSupersetOf(b) | 真偽値 | false |
| a.isDisjointFrom(b) | 真偽値 | false(3と4が共通) |
isDisjointFrom は「共通する要素が1つも無いか」を返すメソッドで、権限の組み合わせが衝突していないかの検査などに使えます。どのメソッドも元のSetは書き換えません。
引数に渡せるのはSetだけではありません。size プロパティと has・keys メソッドを持つ「Setのような」オブジェクトなら受け取るので、Mapを渡すとキーが比較の対象になります。反対に、配列は size を持たないため渡せません。
const a = new Set([1, 2, 3, 4]);
console.log([...a.intersection(new Map([[1, "x"], [9, "y"]]))]);
// [ 1 ]
try {
a.union([1, 2]);
} catch (e) {
console.log(String(e));
}
// TypeError: The .size property is NaN
console.log([...a.union(new Set([1, 2]))]);
// [ 1, 2, 3, 4 ]
配列と比べたいときは new Set(array) で包みます。上のエラーメッセージはNode.js 26.5.0(V8)のもので、ブラウザによって文言は変わります。
Promise.try:同期の例外を拒否に変える仕組みと実行順
Promise.try(fn, ...args) は、fn をその場で同期的に呼び、戻り値をPromiseで包んで返します。fn が同期的に例外を投げた場合も、例外は外へ漏れず、拒否されたPromiseになります。2つ目以降の引数は fn にそのまま渡ります。
function parseConfig(text) {
return JSON.parse(text);
}
Promise.try(parseConfig, "{bad")
.then((cfg) => console.log(cfg))
.catch((e) => console.log("失敗:", e.constructor.name));
// 失敗: SyntaxError
似た書き方の Promise.resolve().then(fn) とは、fn が動くタイミングが違います。次のコードをNode.js 26.5.0で動かすと、記録の順は [ 'try', 'sync', 'then' ] でした。
const order = [];
Promise.try(() => order.push("try"));
Promise.resolve().then(() => order.push("then"));
order.push("sync");
setTimeout(() => console.log(order), 0);
// [ 'try', 'sync', 'then' ]
then に渡した関数はマイクロタスクに回るので、同期処理が終わった後に動きます。Promise.try は呼んだその場で動くので、キャッシュがあれば同期で値を返し、無ければ非同期に取得する、といった関数を1本の .catch() で扱えます。これまで同じ用途で使われてきたnpmの p-try は、Node.js 24以上(23は2025年6月1日にサポート終了)なら不要です。await と try/catch を使った書き方との使い分けはJavaScriptの非同期エラーハンドリングと並列実行|try/catch・Promise.all・allSettledの使い分けで解説しています。
Import AttributesとJSON Modules:assert は Node.js 22 と Chrome 126 で削除
JSONファイルをモジュールとして読み込むには、with の後に type: "json" を書きます。ECMAScriptの仕様が定めているのは、type: "json" を付けたimportをJSONとして扱うことまでで、属性なしの扱いは実行環境に任されています。ブラウザとNode.js・Denoは属性なしのJSON importをエラーにします(Node.js 26.5.0では ERR_IMPORT_ATTRIBUTE_MISSING)。ブラウザはモジュールの種類を拡張子ではなくサーバーが返すMIMEタイプで決めるため、属性が無いと、JSONのつもりで読み込んだURLから text/javascript が返ったときにそのままコードとして実行してしまいます。MDNのImport attributesの解説が、この危険を理由に挙げています。
// config.json の中身: {"port": 8080, "debug": true}
import config from "./config.json" with { type: "json" };
console.log(config.port);
// 8080
// 動的importでは第2引数に渡す
const { default: cfg } = await import("./config.json", { with: { type: "json" } });
2023年ごろまでの解説には assert { type: "json" } という書き方が出てきます。これは仕様が固まる前の旧構文で、ES2025には入っていません。MDNのbrowser-compat-data(8.1.7)では、Chromeは91〜125、Node.jsは16.14.0〜21.7.0だけが対応し、FirefoxとSafariは一度も対応していません。Node.js 26.5.0で旧構文を読み込ませると、次のエラーで止まります。
import config from "./config.json" assert { type: "json" };
^^^^^^
SyntaxError: Unexpected identifier 'assert'
Node.js 20から22以降へ上げたときにこのエラーが出たら、assert を with に置き換えれば動きます。CommonJSの require("./config.json") は従来どおり属性なしでJSONを読めます。ESMとCommonJSを混在させているプロジェクトの読み込み規則はESMとCommonJSの違い|require(esm)で変わった相互運用と移行手順【Node.js 26実測】にまとめています。
正規表現の3機能:モディファイア・重複名前付きグループ・RegExp.escape
パターンモディファイア (?i:…):パターンの一部だけに効く i・m・s フラグ
i(大文字小文字を区別しない)・m(複数行)・s(. が改行にも一致)の3つのフラグを、パターンの一部だけに付け外しできます。(?i:...) で付け、(?-i:...) で外します。
const re = /^(?i:ab)c$/;
console.log(re.test("ABc"));
// true(ab の部分だけ大文字小文字を無視)
console.log(re.test("ABC"));
// false(c は小文字でなければ一致しない)
この機能はSafariの対応が遅く、Safari 26(2025年9月15日)からです。iPhoneの利用者が多いサービスで、Safari 18.xの端末が残っているならまだ使えません。core-jsのポリフィルでもTypeScriptの変換でも補えず、古い構文へ書き換えるにはBabelのプラグインが要ります(後述)。
重複した名前付きキャプチャグループ:書式違いの日付を1つの名前で受ける書き方
| で区切った別々の選択肢の中なら、同じグループ名を2回使えます。「2025-06」と「06/2025」のような書式違いを、どちらも groups.year で受け取れます。
const re = /(?<year>\d{4})-(?<month>\d{2})|(?<month>\d{2})\/(?<year>\d{4})/;
console.log(re.exec("2025-06").groups);
// [Object: null prototype] { year: '2025', month: '06' }
console.log(re.exec("06/2025").groups);
// [Object: null prototype] { year: '2025', month: '06' }
同じ選択肢の中で同じ名前を2回使うと、ES2025でも構文エラーです。
RegExp.escape():ユーザー入力を文字どおりのパターンにする変換規則
検索欄に入った文字列を正規表現に組み込むと、. や * が特殊文字として働きます。「a.b」で検索したつもりが「axb」にも一致してしまうのはこのためです。RegExp.escape() は、文字列を文字どおりに一致するパターンへ変換します。
const input = "a.b";
console.log(new RegExp(input).test("axb"));
// true(. が任意の1文字として働く)
console.log(new RegExp(RegExp.escape(input)).test("axb"));
// false
console.log(RegExp.escape("Hello. World."));
// \x48ello\.\x20World\.
console.log(RegExp.escape("1+1=2"));
// \x31\+1\x3d2
出力の \x48 は先頭の「H」、\x20 は空白です。MDNのRegExp.escape()の解説によると、先頭が数字か英字のときに \xNN へ変えるのは、大きなパターンの中で \1 や \x0 の直後に埋め込んでも、先頭の文字がそのエスケープの一部として読まれないようにするためです。見た目は崩れても、一致する文字列は変わりません。手書きの replace(/[.*+?^${}()|[\]\\]/g, "\\$&") を置き換えられますが、対応はNode.js 24.0.0・Chrome 136からと8機能の中で最も新しい部類です。
Float16Array と Math.f16round:半精度で丸めたときの誤差と上限
Float16Array は1要素2バイトの型付き配列です。機械学習モデルの重みやWebGPUのテクスチャのように、精度より転送量を優先するデータに向きます。Float32Array の半分の容量で済む代わりに、表せる桁と範囲が狭くなります。
const f = new Float16Array([1.1, 65504, 70000, 0.0001]);
console.log(Array.from(f));
// [ 1.099609375, 65504, Infinity, 0.00010001659393310547 ]
console.log(Math.f16round(1.1));
// 1.099609375
const view = new DataView(new ArrayBuffer(2));
view.setFloat16(0, 3.14159);
console.log(view.getFloat16(0));
// 3.140625
1.1は1.099609375に丸められ、有限で表せる最大値は65504です。70000を入れると Infinity になります。金額や件数のように誤差が許されない値には使わず、Math.f16round で事前に丸めて許容できる誤差かを確かめてから採用します。2進数の浮動小数点で誤差が出る仕組みはIEEE 754とは?浮動小数点数のビット表現・誤差・float64の選び方を実測で解説で説明しています。
対応ブラウザとNode.js・TypeScriptの版:ES2025を本番で使う条件
機能ごとの対応版:BCD 8.1.7(2026年10月22日生成)の値
次の表は、MDNの互換性データ @mdn/browser-compat-data 8.1.7の version_added と、web-features 3.44.0のBaseline(主要ブラウザがすべて対応した日)を並べたものです。SafariはiOS版も同じ版です。
| 機能 | Chrome | Firefox | Safari | Node.js | Deno | Bun | Baseline |
|---|---|---|---|---|---|---|---|
| Iterator Helpers | 122 | 131 | 18.4 | 22.0.0 | 1.39 | 1.1.31 | 2025-03-31 |
| Setメソッド | 122 | 127 | 17 | 22.0.0 | 1.42 | 1.0.0 | 2024-06-11 |
| Promise.try | 128 | 134 | 18.2 | 23.0.0 | 1.46 | 1.1.22 | 2025-01-07 |
| JSON Modules | 123 | 138 | 17.2 | 20.10.0 | 1.37 | 1.0.0 | 2025-04-29 |
| モディファイア | 125 | 132 | 26 | 23.0.0 | 1.44 | 1.2.3 | 2025-09-15 |
| 重複グループ名 | 125 | 129 | 17 | 23.0.0 | 1.44 | 1.0.0 | 2024-08-06 |
| RegExp.escape | 136 | 134 | 18.2 | 24.0.0 | 2.3.2 | 1.1.22 | 2025-05-01 |
| Float16Array | 135 | 129 | 18.2 | 24.0.0 | 1.43 | 1.1.23 | 2025-04-04 |
Baseline列はすべて「Newly available」(主要ブラウザの最新版がそろって対応した)の日付です。そこから30か月たつと「Widely available」になりますが、web-features 3.44.0の時点ではES2025の機能はどれもWidely availableに達していません。最も早いSetメソッドでも2026年12月が目安です。古い端末まで支えるサービスでは、この表の版を下限として明示してから使います。
Node.js:22では5機能が動かず、24以上が条件
Node.js 22は2027年4月30日までサポートが続きますが、Promise.try・モディファイア・重複グループ名(いずれも23.0.0から)と、RegExp.escape・Float16Array(24.0.0から)が使えません。Node.jsのリリース計画では、Node.js 24は2026年10月20日からMaintenance LTS(サポート終了は2028年4月30日)、Node.js 26は2026年10月28日からActive LTSです。ES2025を前提にコードを書くなら、実行環境はNode.js 24以上にそろえます。Node.js 20は2026年4月30日にサポートが終了しています。26への移行手順はNode.js 26の新機能と破壊的変更・LTS移行日|24からの移行手順【26.11.1対応】を参照してください。
TypeScript:target と lib の es2025 は6.0から
TypeScriptで "target": "es2025" や "lib": ["es2025"] を書けるのは6.0からです。npmの各版で tsc --target es2025 --lib es2025 を実行したところ、5.9.3は「Argument for ‘–target’ option must be」のエラーで受け付けず、6.0.2と7.0.2は通りました。7.0.2はまだ es2026 を受け付けないので、ES2026の型を使うには esnext を指定します。
// tsconfig.json
{
"compilerOptions": {
"target": "es2025",
"lib": ["es2025", "dom"]
}
}
lib を es2024 のままにすると、7.0.2では Property 'union' does not exist on type 'Set<number>'. ... Try changing the 'lib' compiler option to 'es2025' or later. のように型エラーになります。必要な分だけ足したい場合は es2025.collection・es2025.iterator・es2025.promise・es2025.regexp・es2025.float16 の単位でも指定できます。TypeScript 6.0への移行はTypeScript 6.0とは|5から6への移行手順とts5to6・7.0との違い【6.0.3対応】で解説しています。
ポリフィルで補える機能と補えない構文
lib の指定は型を足すだけで、実行時のメソッドは追加しません。古いブラウザで動かすには、メソッドとして追加された機能はポリフィルで補えます。core-js 3.51.0には es.iterator.map・es.set.union.v2・es.promise.try・es.regexp.escape・es.math.f16round・es.data-view.get-float16 などのモジュールがあります。ただしcore-jsは Float16Array 本体を補いません。core-jsのREADMEには「Float16Array are not polyfilled」とあり、補えるのは Math.f16round と DataView のfloat16メソッドだけです。型付き配列そのものが要るなら @petamoriken/float16(3.9.3)のような別ライブラリを使います。
core-jsなどのポリフィルで補えないのは構文の機能です。ただし正規表現のモディファイアと重複グループ名は、Babel 8の @babel/plugin-transform-regexp-modifiers と @babel/plugin-transform-duplicate-named-capturing-groups-regex(いずれも8.0.1)で古い構文へ変換できます。/^(?i:ab)c$/ は /^(?:[Aa][Bb])c$/ になります。with によるimportは、バンドラーでJSONを取り込むか、実行環境側の対応が必要です。TypeScript 7.0.2で target を es2022 に下げて出力しても、/^(?i:ab)c$/ はそのまま残りました。Safari 26未満を支えるならモディファイアを、Safari 17.2未満も支えるなら重複グループ名と with も、変換なしでは使わないと決めておくのが確実です。ビルドで構文変換を担うツールの選び方はSWCとは?Rust製コンパイラの設定と採用判断を実装目線で解説を参照してください。
対応ブラウザの下限が決まらず、古いNode.jsやブラウザ向けのコードが残る既存システムでは、ES2025への置き換えと実行環境の更新を同時に進めることになります。改修範囲が広く、作り直しも含めて検討する場合はフルスクラッチ開発の進め方を参考にしてください。
よくある質問
ES2025はいつ正式に決まりましたか?
2025年6月25日にEcma Internationalの総会で承認されました。正式名称はECMA-262の第16版です。収録される提案は、その年の春までにTC39でStage 4に達したもので決まり、TC39のプロセス文書によると、3月の会合で版の内容が仕様の本線から切り出され、その後は文言の修正だけが入ります。各提案がどの版に入ったかは、TC39のfinished-proposals.mdで確認できます。
JavaScriptの最新バージョンはES2025ですか?
いいえ。2026年6月に承認されたES2026(第17版)が最新です。ES2026にはMapの getOrInsert、Iterator.concat、Uint8Array のBase64変換、Math.sumPrecise、Error.isError、Array.fromAsync などが入りました。ES2025の機能はES2026でもそのまま使えます。ES2026までの各版の内容はECMAScriptの解説記事にまとめています。
ES2025とES2024の違いは何ですか?
ES2024に入ったのは Object.groupBy・Map.groupBy、Promise.withResolvers、正規表現の v フラグ、ArrayBufferのサイズ変更と transfer などです。ES2025はその次の版で、Iterator Helpers・Setメソッド・Promise.try・Import Attributes・正規表現の3機能・Float16Arrayが加わりました。ArrayBuffer.prototype.transfer をES2025の機能として紹介している解説がありますが、ES2024です。
import … assert { type: “json” } はもう使えませんか?
使えません。Node.js 22.0.0とChrome 126で削除され、FirefoxとSafariは最初から対応していません。Node.js 26.5.0では「SyntaxError: Unexpected identifier ‘assert’」で止まります。assert を with に書き換えるだけで、Node.js 20.10.0以降(22.12.0・20.18.3より前はExperimentalWarningが出る実験的機能)・Chrome 123以降・Firefox 138以降・Safari 17.2以降で動きます。
TypeScriptで es2025 を指定するには何が必要ですか?
TypeScript 6.0以上が必要です。5.9.3では --target es2025 がエラーになり、6.0.2と7.0.2では通ります。tsconfig.jsonの target と lib を es2025 にすると、Setメソッドや Promise.try の型が使えます。型が通っても実行環境が古ければ動かないので、Node.js 24以上か、メソッドはポリフィル、正規表現の構文はBabelでの変換の併用が前提です。