Skip to content

Enable markdown negotiation for agents#451

Merged
frostney merged 3 commits into
mainfrom
t3code/markdown-agent-responses
Apr 29, 2026
Merged

Enable markdown negotiation for agents#451
frostney merged 3 commits into
mainfrom
t3code/markdown-agent-responses

Conversation

@frostney
Copy link
Copy Markdown
Owner

Summary

  • Add Accept: text/markdown negotiation for website page requests via Next proxy rewrites
  • Serve markdown responses with Content-Type: text/markdown, Vary: Accept, and x-markdown-tokens
  • Add generated markdown coverage for home, docs, installation, playground, and sandbox pages

Verification

  • bun test
  • bun run lint
  • bun run build
  • curl confirmed default HTML and markdown response headers locally

@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 29, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
gocciascript-homepage Ready Ready Preview, Comment Apr 29, 2026 10:52am

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 29, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5f1aea2d-dc3d-48bd-8ab1-e1919d08498b

📥 Commits

Reviewing files that changed from the base of the PR and between b30cfa3 and 4b37f5d.

📒 Files selected for processing (2)
  • website/src/__tests__/markdown-negotiation.test.ts
  • website/src/lib/site-markdown.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • website/src/tests/markdown-negotiation.test.ts

📝 Walkthrough

Walkthrough

Adds markdown negotiation utilities, a proxy middleware that rewrites eligible requests to an agent-markdown route, a dynamic Node route handler for GET/HEAD returning markdown, server-side site-markdown generation for several routes, and tests covering negotiation and generation.

Changes

Cohort / File(s) Summary
Tests
website/src/__tests__/markdown-negotiation.test.ts
New Bun tests for Accept header parsing/q-values, acceptsMarkdown, markdownResponseHeaders, resolveMarkdownRoute, yamlScalar, and createSiteMarkdown output.
Markdown negotiation utilities
website/src/lib/markdown-negotiation.ts
Adds MARKDOWN_CONTENT_TYPE, MARKDOWN_ROUTE_PREFIX, acceptsMarkdown(…) with q-value parsing/clamping, estimateMarkdownTokens(…), and markdownResponseHeaders(…).
Site markdown generator
website/src/lib/site-markdown.ts
New MarkdownRoute type, resolveMarkdownRoute(…), yamlScalar, route builders (home, docs, installation, playground, sandbox), createSiteMarkdown(…) dispatcher; includes doc source loading, example selection, and GitHub release fetching.
Route handler
website/src/app/agent-markdown/[[...path]]/route.ts
New dynamic Node runtime route exporting runtime, dynamic, GET, HEAD, and MarkdownContext; resolves segments, calls createSiteMarkdown, returns 200/404 with markdownResponseHeaders, body present only for GET.
Middleware proxy
website/src/proxy.ts
New Next.js middleware proxy and config.matcher that rewrites eligible GET/HEAD requests with Accept: text/markdown to the markdown prefix, skipping API/_next/static/asset/file-like paths and the prefix itself.

Sequence Diagram

sequenceDiagram
    participant Client as Client
    participant Proxy as Proxy\nMiddleware
    participant Route as Agent-Markdown\nRoute Handler
    participant Site as Site-Markdown\nGenerator

    Client->>Proxy: GET /docs/readme\nAccept: text/markdown
    Proxy->>Proxy: acceptsMarkdown(Accept)
    Proxy->>Proxy: check exclusions (/_next, /api, assets, file.ext, prefix)
    Proxy->>Route: rewrite -> /agent-markdown/docs/readme
    Route->>Route: extract segments & searchParams
    Route->>Site: createSiteMarkdown(["docs","readme"], searchParams)
    Site->>Site: resolveMarkdownRoute -> docs\nload doc source / fetch release / pick example
    Site-->>Route: return markdown string (or null)
    Route->>Route: headers = markdownResponseHeaders(markdown)
    Route->>Client: respond 200/404 with headers (body only for GET)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: enabling markdown negotiation for agents, which is directly reflected in the implementation of Accept header negotiation and markdown response serving across multiple files.
Description check ✅ Passed The description provides a clear summary of changes and verification steps performed, but deviates from the repository template by not following the exact required structure with explicit Testing checkbox sections.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Review rate limit: 0/5 reviews remaining, refill in 59 minutes and 14 seconds.

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 29, 2026

Benchmark Results

407 benchmarks

Interpreted: 🟢 33 improved · 🔴 228 regressed · 146 unchanged · avg -3.5%
Bytecode: 🟢 193 improved · 🔴 42 regressed · 172 unchanged · avg +4.7%

arraybuffer.js — Interp: 🟢 1, 🔴 8, 5 unch. · avg -5.1% · Bytecode: 🟢 8, 6 unch. · avg +4.9%
Benchmark Interpreted Δ Bytecode Δ
create ArrayBuffer(0) 192,337 ops/sec [150,752..193,931] → 181,506 ops/sec [140,677..187,367] ~ overlap (-5.6%) 222,045 ops/sec [136,974..226,806] → 233,129 ops/sec [210,102..236,780] ~ overlap (+5.0%)
create ArrayBuffer(64) 185,017 ops/sec [183,379..188,458] → 177,968 ops/sec [175,394..184,336] ~ overlap (-3.8%) 214,831 ops/sec [213,516..216,837] → 220,329 ops/sec [177,672..225,356] ~ overlap (+2.6%)
create ArrayBuffer(1024) 163,791 ops/sec [162,187..165,965] → 151,237 ops/sec [146,288..153,513] 🔴 -7.7% 180,694 ops/sec [178,259..182,603] → 193,859 ops/sec [192,113..194,593] 🟢 +7.3%
create ArrayBuffer(8192) 96,564 ops/sec [95,769..97,736] → 81,747 ops/sec [50,200..82,454] 🔴 -15.3% 91,713 ops/sec [88,258..93,217] → 103,096 ops/sec [100,244..104,234] 🟢 +12.4%
slice full buffer (64 bytes) 204,970 ops/sec [181,520..205,969] → 184,276 ops/sec [166,001..191,325] ~ overlap (-10.1%) 254,197 ops/sec [158,901..265,065] → 261,100 ops/sec [257,056..264,609] ~ overlap (+2.7%)
slice half buffer (512 of 1024 bytes) 186,346 ops/sec [185,449..186,843] → 175,676 ops/sec [172,019..177,009] 🔴 -5.7% 226,166 ops/sec [222,062..231,594] → 236,573 ops/sec [224,988..238,316] ~ overlap (+4.6%)
slice with negative indices 172,999 ops/sec [171,255..174,050] → 164,603 ops/sec [162,951..167,085] 🔴 -4.9% 235,061 ops/sec [229,900..239,093] → 245,545 ops/sec [243,568..248,810] 🟢 +4.5%
slice empty range 196,669 ops/sec [194,992..198,552] → 186,945 ops/sec [185,205..192,555] 🔴 -4.9% 244,229 ops/sec [240,767..252,890] → 254,788 ops/sec [249,163..255,414] ~ overlap (+4.3%)
byteLength access 432,155 ops/sec [427,714..437,063] → 434,450 ops/sec [427,460..447,056] ~ overlap (+0.5%) 652,195 ops/sec [648,612..661,511] → 676,311 ops/sec [669,284..679,712] 🟢 +3.7%
Symbol.toStringTag access 359,842 ops/sec [354,992..365,261] → 370,726 ops/sec [366,034..374,686] 🟢 +3.0% 424,846 ops/sec [420,103..426,865] → 442,714 ops/sec [433,996..447,994] 🟢 +4.2%
ArrayBuffer.isView 269,421 ops/sec [264,247..269,919] → 264,569 ops/sec [261,421..266,839] ~ overlap (-1.8%) 328,439 ops/sec [322,389..338,608] → 339,752 ops/sec [337,763..342,008] ~ overlap (+3.4%)
clone ArrayBuffer(64) 182,750 ops/sec [179,245..183,462] → 174,989 ops/sec [171,517..179,147] 🔴 -4.2% 213,482 ops/sec [209,349..216,094] → 224,182 ops/sec [219,507..225,021] 🟢 +5.0%
clone ArrayBuffer(1024) 160,554 ops/sec [158,893..162,004] → 148,675 ops/sec [147,139..150,210] 🔴 -7.4% 179,668 ops/sec [177,294..182,031] → 191,908 ops/sec [188,867..194,150] 🟢 +6.8%
clone ArrayBuffer inside object 127,229 ops/sec [125,762..129,015] → 122,822 ops/sec [121,920..124,144] 🔴 -3.5% 144,914 ops/sec [142,152..145,947] → 146,931 ops/sec [146,542..148,158] 🟢 +1.4%
arrays.js — Interp: 🔴 10, 9 unch. · avg -3.4% · Bytecode: 🟢 12, 7 unch. · avg +4.3%
Benchmark Interpreted Δ Bytecode Δ
Array.from length 100 4,297 ops/sec [4,170..4,303] → 4,147 ops/sec [3,300..4,190] ~ overlap (-3.5%) 6,718 ops/sec [6,670..6,754] → 6,711 ops/sec [6,213..6,908] ~ overlap (-0.1%)
Array.from 10 elements 97,337 ops/sec [95,503..97,970] → 92,832 ops/sec [71,454..93,480] 🔴 -4.6% 96,395 ops/sec [92,416..97,015] → 100,979 ops/sec [65,402..102,560] ~ overlap (+4.8%)
Array.of 10 elements 117,009 ops/sec [116,139..118,649] → 113,536 ops/sec [111,637..115,473] 🔴 -3.0% 122,221 ops/sec [121,233..122,950] → 129,023 ops/sec [127,530..129,189] 🟢 +5.6%
spread into new array 144,674 ops/sec [142,711..145,350] → 137,891 ops/sec [137,077..139,247] 🔴 -4.7% 76,216 ops/sec [64,266..76,777] → 83,058 ops/sec [78,996..84,194] 🟢 +9.0%
map over 50 elements 7,351 ops/sec [7,324..7,357] → 6,350 ops/sec [4,737..7,121] 🔴 -13.6% 12,396 ops/sec [12,340..12,460] → 12,867 ops/sec [12,555..12,979] 🟢 +3.8%
filter over 50 elements 6,680 ops/sec [6,665..6,748] → 6,581 ops/sec [6,360..6,669] ~ overlap (-1.5%) 12,064 ops/sec [11,783..12,256] → 12,246 ops/sec [12,085..12,375] ~ overlap (+1.5%)
reduce sum 50 elements 7,527 ops/sec [7,429..7,580] → 7,358 ops/sec [7,322..7,610] ~ overlap (-2.3%) 11,705 ops/sec [11,568..12,080] → 12,119 ops/sec [11,970..12,252] ~ overlap (+3.5%)
forEach over 50 elements 6,813 ops/sec [6,686..6,885] → 6,772 ops/sec [6,648..6,883] ~ overlap (-0.6%) 11,439 ops/sec [11,317..11,560] → 12,197 ops/sec [12,002..12,276] 🟢 +6.6%
find in 50 elements 9,843 ops/sec [9,573..10,047] → 9,632 ops/sec [9,537..9,701] ~ overlap (-2.1%) 17,831 ops/sec [17,764..18,032] → 18,475 ops/sec [18,248..18,578] 🟢 +3.6%
sort 20 elements 3,683 ops/sec [3,645..3,726] → 3,740 ops/sec [3,708..3,757] ~ overlap (+1.5%) 6,992 ops/sec [6,883..7,047] → 7,002 ops/sec [6,898..7,085] ~ overlap (+0.2%)
flat nested array 50,509 ops/sec [50,008..51,198] → 48,489 ops/sec [48,461..48,560] 🔴 -4.0% 49,789 ops/sec [49,564..50,441] → 53,436 ops/sec [52,987..53,872] 🟢 +7.3%
flatMap 29,180 ops/sec [28,924..29,799] → 27,508 ops/sec [27,307..28,045] 🔴 -5.7% 34,439 ops/sec [33,786..34,636] → 36,192 ops/sec [35,446..36,532] 🟢 +5.1%
map inside map (5x5) 7,721 ops/sec [7,573..7,831] → 7,305 ops/sec [7,265..7,424] 🔴 -5.4% 10,177 ops/sec [10,084..10,232] → 10,688 ops/sec [10,554..10,738] 🟢 +5.0%
filter inside map (5x10) 5,378 ops/sec [5,361..5,396] → 5,222 ops/sec [5,208..5,252] 🔴 -2.9% 8,265 ops/sec [8,092..8,373] → 8,363 ops/sec [8,308..8,510] ~ overlap (+1.2%)
reduce inside map (5x10) 6,063 ops/sec [6,013..6,153] → 6,121 ops/sec [6,091..6,140] ~ overlap (+1.0%) 9,004 ops/sec [8,883..9,173] → 9,236 ops/sec [9,191..9,459] 🟢 +2.6%
forEach inside forEach (5x10) 5,407 ops/sec [5,285..5,442] → 5,348 ops/sec [5,205..5,419] ~ overlap (-1.1%) 9,103 ops/sec [8,629..9,232] → 9,300 ops/sec [9,240..9,345] 🟢 +2.2%
find inside some (10x10) 4,488 ops/sec [4,418..4,520] → 4,238 ops/sec [3,877..4,345] 🔴 -5.6% 7,088 ops/sec [7,042..7,170] → 7,492 ops/sec [7,365..7,542] 🟢 +5.7%
map+filter chain nested (5x20) 1,637 ops/sec [1,617..1,670] → 1,601 ops/sec [1,581..1,634] ~ overlap (-2.2%) 2,718 ops/sec [2,628..2,770] → 2,757 ops/sec [2,717..2,775] ~ overlap (+1.4%)
reduce flatten (10x5) 17,589 ops/sec [17,320..17,701] → 16,794 ops/sec [16,456..17,106] 🔴 -4.5% 7,343 ops/sec [7,228..7,407] → 8,289 ops/sec [8,086..8,341] 🟢 +12.9%
async-await.js — Interp: 🔴 5, 1 unch. · avg -8.2% · Bytecode: 🟢 3, 3 unch. · avg +10.1%
Benchmark Interpreted Δ Bytecode Δ
single await 158,801 ops/sec [120,473..162,636] → 145,906 ops/sec [106,134..149,768] ~ overlap (-8.1%) 155,451 ops/sec [128,811..172,154] → 181,794 ops/sec [152,804..182,214] ~ overlap (+16.9%)
multiple awaits 75,853 ops/sec [74,702..76,461] → 71,636 ops/sec [70,152..72,586] 🔴 -5.6% 74,283 ops/sec [71,383..75,664] → 78,315 ops/sec [55,000..81,289] ~ overlap (+5.4%)
await non-Promise value 311,668 ops/sec [307,073..313,616] → 294,191 ops/sec [289,634..296,116] 🔴 -5.6% 409,516 ops/sec [405,265..416,648] → 456,499 ops/sec [454,409..459,385] 🟢 +11.5%
await with try/catch 150,263 ops/sec [149,617..151,839] → 144,567 ops/sec [143,636..145,010] 🔴 -3.8% 160,616 ops/sec [156,394..164,306] → 182,513 ops/sec [180,170..183,978] 🟢 +13.6%
await Promise.all 25,241 ops/sec [24,938..25,295] → 20,516 ops/sec [15,896..23,001] 🔴 -18.7% 22,015 ops/sec [15,686..22,862] → 24,292 ops/sec [23,177..25,142] 🟢 +10.3%
nested async function call 83,823 ops/sec [83,458..84,483] → 77,860 ops/sec [59,069..78,939] 🔴 -7.1% 102,142 ops/sec [99,023..103,635] → 104,781 ops/sec [103,551..106,564] ~ overlap (+2.6%)
async-generators.js — Interp: 🔴 2 · avg -9.1% · Bytecode: 2 unch. · avg +4.9%
Benchmark Interpreted Δ Bytecode Δ
for-await-of over async generator 3,757 ops/sec [3,629..3,856] → 3,410 ops/sec [3,281..3,437] 🔴 -9.2% 571 ops/sec [556..579] → 604 ops/sec [557..607] ~ overlap (+5.8%)
async generator with await in body 27,101 ops/sec [26,839..27,419] → 24,677 ops/sec [23,895..24,809] 🔴 -8.9% 18,531 ops/sec [18,173..18,630] → 19,288 ops/sec [18,623..19,701] ~ overlap (+4.1%)
base64.js — Interp: 🔴 9, 1 unch. · avg -6.9% · Bytecode: 🟢 6, 4 unch. · avg +4.8%
Benchmark Interpreted Δ Bytecode Δ
short ASCII (13 chars) 4,751 ops/sec [4,614..4,836] → 4,235 ops/sec [4,201..4,248] 🔴 -10.9% 4,290 ops/sec [4,261..4,340] → 4,678 ops/sec [4,629..4,750] 🟢 +9.0%
medium ASCII (450 chars) 170 ops/sec [170..171] → 139 ops/sec [105..169] 🔴 -18.5% 154 ops/sec [127..163] → 171 ops/sec [134..173] ~ overlap (+11.4%)
Latin-1 characters 6,649 ops/sec [6,583..6,676] → 6,340 ops/sec [6,053..6,449] 🔴 -4.7% 6,365 ops/sec [6,298..6,398] → 6,619 ops/sec [5,299..6,798] ~ overlap (+4.0%)
short base64 (20 chars) 2,557 ops/sec [2,501..2,570] → 2,432 ops/sec [2,308..2,518] ~ overlap (-4.9%) 2,459 ops/sec [2,453..2,468] → 2,578 ops/sec [2,573..2,598] 🟢 +4.8%
medium base64 (600 chars) 108 ops/sec [107..111] → 103 ops/sec [102..106] 🔴 -4.4% 106 ops/sec [105..108] → 108 ops/sec [104..111] ~ overlap (+1.1%)
Latin-1 output 3,563 ops/sec [3,535..3,579] → 3,370 ops/sec [3,322..3,394] 🔴 -5.4% 3,494 ops/sec [3,452..3,524] → 3,565 ops/sec [3,538..3,592] 🟢 +2.0%
forgiving (no padding) 5,365 ops/sec [5,313..5,421] → 5,004 ops/sec [4,923..5,156] 🔴 -6.7% 5,169 ops/sec [5,106..5,265] → 5,222 ops/sec [5,180..5,250] ~ overlap (+1.0%)
with whitespace 2,332 ops/sec [2,316..2,337] → 2,200 ops/sec [2,180..2,208] 🔴 -5.7% 2,205 ops/sec [2,161..2,255] → 2,273 ops/sec [2,256..2,305] 🟢 +3.1%
atob(btoa(short)) 1,641 ops/sec [1,624..1,653] → 1,579 ops/sec [1,560..1,584] 🔴 -3.7% 1,571 ops/sec [1,560..1,586] → 1,650 ops/sec [1,619..1,660] 🟢 +5.0%
atob(btoa(medium)) 67 ops/sec [67..67] → 64 ops/sec [63..65] 🔴 -3.8% 63 ops/sec [63..64] → 67 ops/sec [67..67] 🟢 +6.0%
classes.js — Interp: 🔴 24, 7 unch. · avg -4.1% · Bytecode: 🟢 5, 🔴 2, 24 unch. · avg +1.5%
Benchmark Interpreted Δ Bytecode Δ
simple class new 61,275 ops/sec [60,130..61,840] → 58,885 ops/sec [57,158..59,440] 🔴 -3.9% 85,681 ops/sec [85,500..85,762] → 86,654 ops/sec [85,481..87,212] ~ overlap (+1.1%)
class with defaults 48,883 ops/sec [48,575..49,324] → 46,221 ops/sec [46,112..46,364] 🔴 -5.4% 59,488 ops/sec [58,567..59,492] → 58,591 ops/sec [56,142..59,451] ~ overlap (-1.5%)
50 instances via Array.from 2,266 ops/sec [2,232..2,308] → 2,218 ops/sec [2,194..2,258] ~ overlap (-2.1%) 3,804 ops/sec [3,765..3,811] → 3,668 ops/sec [3,661..3,691] 🔴 -3.6%
instance method call 29,328 ops/sec [29,303..29,582] → 28,259 ops/sec [27,567..28,917] 🔴 -3.6% 44,004 ops/sec [43,812..44,136] → 43,113 ops/sec [42,913..43,429] 🔴 -2.0%
static method call 45,672 ops/sec [45,523..45,943] → 43,135 ops/sec [42,523..44,017] 🔴 -5.6% 77,964 ops/sec [76,422..79,454] → 80,160 ops/sec [79,934..80,343] 🟢 +2.8%
single-level inheritance 24,627 ops/sec [24,491..24,789] → 23,609 ops/sec [23,097..24,034] 🔴 -4.1% 32,069 ops/sec [31,525..32,565] → 33,460 ops/sec [33,038..33,585] 🟢 +4.3%
two-level inheritance 21,537 ops/sec [21,372..21,673] → 20,509 ops/sec [20,372..20,648] 🔴 -4.8% 25,429 ops/sec [25,196..25,697] → 26,533 ops/sec [26,426..26,678] 🟢 +4.3%
private field access 32,650 ops/sec [32,552..32,800] → 31,177 ops/sec [30,974..31,315] 🔴 -4.5% 43,663 ops/sec [43,350..44,157] → 44,744 ops/sec [44,450..44,817] 🟢 +2.5%
private methods 35,800 ops/sec [35,636..36,006] → 34,268 ops/sec [33,745..34,438] 🔴 -4.3% 47,563 ops/sec [47,107..47,915] → 48,073 ops/sec [47,911..48,882] ~ overlap (+1.1%)
getter/setter access 32,446 ops/sec [31,820..32,922] → 31,469 ops/sec [31,011..31,698] 🔴 -3.0% 45,390 ops/sec [37,118..48,284] → 49,658 ops/sec [49,264..50,147] 🟢 +9.4%
class decorator (identity) 44,627 ops/sec [44,538..45,159] → 41,960 ops/sec [40,957..42,695] 🔴 -6.0% 50,024 ops/sec [49,581..51,067] → 51,479 ops/sec [50,694..51,919] ~ overlap (+2.9%)
class decorator (wrapping) 26,137 ops/sec [26,040..26,160] → 24,705 ops/sec [24,689..24,777] 🔴 -5.5% 27,092 ops/sec [26,906..27,633] → 28,163 ops/sec [27,620..28,929] ~ overlap (+4.0%)
identity method decorator 32,818 ops/sec [32,517..32,982] → 30,522 ops/sec [29,999..31,109] 🔴 -7.0% 41,922 ops/sec [40,590..42,830] → 42,739 ops/sec [41,936..43,969] ~ overlap (+1.9%)
wrapping method decorator 25,969 ops/sec [25,522..26,267] → 24,895 ops/sec [24,522..25,149] 🔴 -4.1% 31,499 ops/sec [30,838..32,543] → 31,816 ops/sec [31,080..33,033] ~ overlap (+1.0%)
stacked method decorators (x3) 18,237 ops/sec [17,967..18,550] → 16,820 ops/sec [16,752..17,272] 🔴 -7.8% 21,589 ops/sec [21,216..22,776] → 22,332 ops/sec [21,683..22,808] ~ overlap (+3.4%)
identity field decorator 36,127 ops/sec [35,348..36,465] → 34,012 ops/sec [33,794..34,078] 🔴 -5.9% 38,336 ops/sec [37,555..39,776] → 39,468 ops/sec [38,568..40,448] ~ overlap (+3.0%)
field initializer decorator 29,783 ops/sec [29,372..30,479] → 28,621 ops/sec [28,436..29,069] 🔴 -3.9% 33,745 ops/sec [33,359..34,606] → 33,559 ops/sec [32,945..34,653] ~ overlap (-0.6%)
getter decorator (identity) 32,543 ops/sec [31,858..33,104] → 31,335 ops/sec [30,930..31,759] 🔴 -3.7% 37,594 ops/sec [37,349..37,971] → 38,280 ops/sec [37,479..38,945] ~ overlap (+1.8%)
setter decorator (identity) 26,641 ops/sec [26,434..26,812] → 26,033 ops/sec [25,370..26,234] 🔴 -2.3% 31,594 ops/sec [31,338..31,857] → 31,888 ops/sec [31,268..32,313] ~ overlap (+0.9%)
static method decorator 33,640 ops/sec [33,302..34,480] → 31,899 ops/sec [30,396..32,644] 🔴 -5.2% 41,788 ops/sec [41,307..43,108] → 43,807 ops/sec [42,896..44,425] ~ overlap (+4.8%)
static field decorator 40,838 ops/sec [40,114..41,267] → 39,065 ops/sec [37,806..39,484] 🔴 -4.3% 43,405 ops/sec [42,581..44,726] → 44,645 ops/sec [41,601..45,585] ~ overlap (+2.9%)
private method decorator 26,311 ops/sec [26,006..26,759] → 25,540 ops/sec [24,725..25,809] 🔴 -2.9% 36,726 ops/sec [36,243..37,538] → 37,811 ops/sec [36,422..38,676] ~ overlap (+3.0%)
private field decorator 29,582 ops/sec [29,333..30,158] → 28,688 ops/sec [28,129..29,036] 🔴 -3.0% 32,662 ops/sec [32,511..33,431] → 34,064 ops/sec [33,155..36,123] ~ overlap (+4.3%)
plain auto-accessor (no decorator) 50,421 ops/sec [49,919..53,717] → 48,862 ops/sec [47,549..51,519] ~ overlap (-3.1%) 50,041 ops/sec [47,341..53,699] → 46,669 ops/sec [46,045..48,748] ~ overlap (-6.7%)
auto-accessor with decorator 28,821 ops/sec [28,333..29,050] → 27,544 ops/sec [26,925..28,980] ~ overlap (-4.4%) 28,958 ops/sec [28,038..30,194] → 30,609 ops/sec [28,000..31,948] ~ overlap (+5.7%)
decorator writing metadata 22,854 ops/sec [22,641..23,548] → 21,682 ops/sec [21,242..22,096] 🔴 -5.1% 25,532 ops/sec [25,064..26,211] → 24,907 ops/sec [23,995..25,396] ~ overlap (-2.4%)
static getter read 58,459 ops/sec [58,342..58,632] → 57,789 ops/sec [56,520..58,473] ~ overlap (-1.1%) 82,822 ops/sec [81,373..83,778] → 84,670 ops/sec [83,204..86,136] ~ overlap (+2.2%)
static getter/setter pair 43,465 ops/sec [43,164..44,357] → 42,964 ops/sec [42,442..43,690] ~ overlap (-1.2%) 57,487 ops/sec [56,488..57,952] → 55,867 ops/sec [52,673..57,855] ~ overlap (-2.8%)
inherited static getter 35,852 ops/sec [35,801..35,989] → 34,642 ops/sec [33,889..35,135] 🔴 -3.4% 43,124 ops/sec [42,455..43,407] → 43,551 ops/sec [43,062..43,604] ~ overlap (+1.0%)
inherited static setter 38,820 ops/sec [38,592..38,939] → 37,959 ops/sec [37,029..38,810] ~ overlap (-2.2%) 46,060 ops/sec [43,877..46,852] → 45,092 ops/sec [44,393..45,835] ~ overlap (-2.1%)
inherited static getter with this binding 31,838 ops/sec [31,654..31,855] → 31,012 ops/sec [30,463..31,881] ~ overlap (-2.6%) 38,432 ops/sec [38,011..38,946] → 38,325 ops/sec [36,822..39,292] ~ overlap (-0.3%)
closures.js — Interp: 🔴 7, 4 unch. · avg -3.5% · Bytecode: 🟢 3, 8 unch. · avg +2.1%
Benchmark Interpreted Δ Bytecode Δ
closure over single variable 49,756 ops/sec [49,143..50,216] → 48,650 ops/sec [46,712..49,052] 🔴 -2.2% 141,238 ops/sec [138,559..144,169] → 151,507 ops/sec [148,262..152,538] 🟢 +7.3%
closure over multiple variables 50,221 ops/sec [49,341..50,715] → 48,462 ops/sec [47,302..49,961] ~ overlap (-3.5%) 137,932 ops/sec [137,149..138,581] → 137,753 ops/sec [137,122..139,168] ~ overlap (-0.1%)
nested closures 54,296 ops/sec [53,509..55,007] → 52,849 ops/sec [52,015..54,178] ~ overlap (-2.7%) 138,783 ops/sec [137,691..140,955] → 141,432 ops/sec [139,767..143,936] ~ overlap (+1.9%)
function as argument 36,243 ops/sec [35,518..37,206] → 35,497 ops/sec [34,657..36,216] ~ overlap (-2.1%) 142,742 ops/sec [64,946..145,090] → 146,254 ops/sec [145,612..147,026] 🟢 +2.5%
function returning function 47,918 ops/sec [47,371..48,792] → 46,377 ops/sec [45,656..47,335] 🔴 -3.2% 156,844 ops/sec [139,371..160,725] → 161,960 ops/sec [158,710..163,550] ~ overlap (+3.3%)
compose two functions 29,839 ops/sec [29,697..29,946] → 28,908 ops/sec [28,062..29,786] ~ overlap (-3.1%) 91,766 ops/sec [85,557..94,017] → 93,877 ops/sec [93,492..94,091] ~ overlap (+2.3%)
fn.call 65,512 ops/sec [65,172..66,006] → 63,055 ops/sec [61,388..64,253] 🔴 -3.8% 93,969 ops/sec [93,349..95,022] → 96,090 ops/sec [94,558..96,628] ~ overlap (+2.3%)
fn.apply 52,090 ops/sec [51,933..52,197] → 50,176 ops/sec [49,228..50,900] 🔴 -3.7% 94,602 ops/sec [93,486..95,634] → 98,888 ops/sec [98,525..99,203] 🟢 +4.5%
fn.bind 63,266 ops/sec [62,218..65,356] → 60,192 ops/sec [56,611..61,989] 🔴 -4.9% 169,435 ops/sec [167,772..173,141] → 172,765 ops/sec [170,979..174,176] ~ overlap (+2.0%)
recursive sum to 50 4,504 ops/sec [4,455..4,572] → 4,238 ops/sec [4,132..4,310] 🔴 -5.9% 18,487 ops/sec [18,085..18,980] → 18,210 ops/sec [18,121..18,310] ~ overlap (-1.5%)
recursive tree traversal 8,112 ops/sec [8,033..8,166] → 7,785 ops/sec [7,719..7,855] 🔴 -4.0% 19,503 ops/sec [18,850..20,213] → 19,360 ops/sec [19,246..19,458] ~ overlap (-0.7%)
collections.js — Interp: 🟢 1, 🔴 10, 1 unch. · avg -6.1% · Bytecode: 🟢 10, 2 unch. · avg +5.8%
Benchmark Interpreted Δ Bytecode Δ
add 50 elements 3,356 ops/sec [3,298..3,378] → 3,146 ops/sec [3,085..3,163] 🔴 -6.2% 3,695 ops/sec [3,676..3,721] → 3,904 ops/sec [3,884..3,914] 🟢 +5.7%
has lookup (50 elements) 49,859 ops/sec [49,207..50,031] → 45,026 ops/sec [44,865..45,801] 🔴 -9.7% 51,608 ops/sec [50,829..52,032] → 54,956 ops/sec [54,902..55,895] 🟢 +6.5%
delete elements 27,231 ops/sec [27,137..27,454] → 24,587 ops/sec [24,437..24,708] 🔴 -9.7% 26,501 ops/sec [26,220..26,795] → 29,051 ops/sec [28,625..29,450] 🟢 +9.6%
forEach iteration 5,700 ops/sec [5,631..5,744] → 5,845 ops/sec [5,825..5,854] 🟢 +2.5% 8,710 ops/sec [5,863..8,781] → 8,545 ops/sec [7,521..8,649] ~ overlap (-1.9%)
spread to array 17,097 ops/sec [16,875..17,167] → 16,000 ops/sec [15,793..16,316] 🔴 -6.4% 106,761 ops/sec [106,656..107,158] → 115,149 ops/sec [113,572..116,229] 🟢 +7.9%
deduplicate array 23,144 ops/sec [22,942..23,296] → 21,333 ops/sec [21,005..21,704] 🔴 -7.8% 35,780 ops/sec [35,038..36,543] → 39,464 ops/sec [39,327..39,777] 🟢 +10.3%
set 50 entries 2,457 ops/sec [2,428..2,490] → 2,289 ops/sec [2,266..2,308] 🔴 -6.8% 2,772 ops/sec [2,739..2,797] → 2,922 ops/sec [2,900..2,938] 🟢 +5.4%
get lookup (50 entries) 46,990 ops/sec [46,566..47,462] → 43,856 ops/sec [43,168..44,290] 🔴 -6.7% 45,695 ops/sec [45,541..46,036] → 48,874 ops/sec [48,417..49,496] 🟢 +7.0%
has check 68,304 ops/sec [67,828..68,543] → 63,636 ops/sec [62,994..65,565] 🔴 -6.8% 69,352 ops/sec [68,486..69,983] → 72,558 ops/sec [72,197..72,691] 🟢 +4.6%
delete entries 26,035 ops/sec [25,749..26,105] → 24,073 ops/sec [23,920..24,172] 🔴 -7.5% 24,676 ops/sec [24,471..25,114] → 26,012 ops/sec [25,886..26,179] 🟢 +5.4%
forEach iteration 5,776 ops/sec [5,734..5,787] → 5,684 ops/sec [5,625..5,749] ~ overlap (-1.6%) 8,578 ops/sec [8,463..8,695] → 8,605 ops/sec [8,570..8,665] ~ overlap (+0.3%)
keys/values/entries 4,780 ops/sec [4,689..4,822] → 4,476 ops/sec [4,395..4,500] 🔴 -6.4% 13,917 ops/sec [13,840..14,177] → 15,081 ops/sec [15,044..15,256] 🟢 +8.4%
csv.js — Interp: 🟢 2, 🔴 4, 7 unch. · avg -1.3% · Bytecode: 🟢 7, 🔴 1, 5 unch. · avg +2.0%
Benchmark Interpreted Δ Bytecode Δ
parse simple 3-column CSV 49,732 ops/sec [48,868..50,363] → 48,951 ops/sec [48,363..49,125] ~ overlap (-1.6%) 52,000 ops/sec [51,350..52,441] → 51,827 ops/sec [50,927..52,445] ~ overlap (-0.3%)
parse 10-row CSV 13,551 ops/sec [13,346..14,293] → 13,660 ops/sec [13,435..13,875] ~ overlap (+0.8%) 14,138 ops/sec [13,961..14,511] → 14,295 ops/sec [14,027..14,672] ~ overlap (+1.1%)
parse 100-row CSV 2,067 ops/sec [2,054..2,069] → 2,065 ops/sec [2,036..2,121] ~ overlap (-0.1%) 2,131 ops/sec [2,113..2,143] → 2,248 ops/sec [2,233..2,260] 🟢 +5.5%
parse CSV with quoted fields 72,264 ops/sec [71,718..72,873] → 69,946 ops/sec [69,031..70,905] 🔴 -3.2% 72,503 ops/sec [72,077..72,994] → 77,375 ops/sec [76,373..80,120] 🟢 +6.7%
parse without headers (array of arrays) 5,952 ops/sec [5,704..5,995] → 5,707 ops/sec [5,582..6,006] ~ overlap (-4.1%) 5,906 ops/sec [5,895..5,922] → 6,241 ops/sec [6,203..6,308] 🟢 +5.7%
parse with semicolon delimiter 9,776 ops/sec [9,732..9,792] → 9,460 ops/sec [9,415..10,005] ~ overlap (-3.2%) 10,134 ops/sec [10,013..10,301] → 10,404 ops/sec [10,339..10,556] 🟢 +2.7%
stringify array of objects 65,800 ops/sec [65,527..66,124] → 67,086 ops/sec [66,692..68,912] 🟢 +2.0% 74,653 ops/sec [73,673..75,206] → 72,080 ops/sec [69,190..75,374] ~ overlap (-3.4%)
stringify array of arrays 23,029 ops/sec [22,968..23,263] → 23,545 ops/sec [23,300..23,887] 🟢 +2.2% 25,129 ops/sec [25,005..25,314] → 24,250 ops/sec [24,082..24,400] 🔴 -3.5%
stringify with values needing escaping 49,484 ops/sec [49,257..49,843] → 48,435 ops/sec [48,189..48,748] 🔴 -2.1% 53,122 ops/sec [52,865..53,665] → 53,055 ops/sec [52,693..55,211] ~ overlap (-0.1%)
reviver converts numbers 1,415 ops/sec [1,402..1,425] → 1,380 ops/sec [1,366..1,395] 🔴 -2.5% 1,550 ops/sec [1,545..1,555] → 1,659 ops/sec [1,651..1,682] 🟢 +7.0%
reviver filters empty to null 11,375 ops/sec [11,223..11,516] → 11,193 ops/sec [11,073..11,478] ~ overlap (-1.6%) 13,998 ops/sec [13,880..14,178] → 14,813 ops/sec [14,711..15,582] 🟢 +5.8%
parse then stringify 8,381 ops/sec [8,314..8,518] → 8,240 ops/sec [8,115..8,286] 🔴 -1.7% 8,693 ops/sec [8,640..8,784] → 8,878 ops/sec [8,816..9,055] 🟢 +2.1%
stringify then parse 8,130 ops/sec [8,073..8,137] → 8,028 ops/sec [7,985..8,099] ~ overlap (-1.3%) 8,499 ops/sec [8,441..8,595] → 8,226 ops/sec [8,152..8,843] ~ overlap (-3.2%)
destructuring.js — Interp: 🔴 7, 15 unch. · avg -2.2% · Bytecode: 🟢 14, 8 unch. · avg +5.6%
Benchmark Interpreted Δ Bytecode Δ
simple array destructuring 178,136 ops/sec [175,051..180,056] → 178,080 ops/sec [165,843..182,441] ~ overlap (-0.0%) 121,724 ops/sec [118,402..126,986] → 126,277 ops/sec [125,567..126,954] ~ overlap (+3.7%)
with rest element 122,800 ops/sec [121,121..123,534] → 117,903 ops/sec [109,025..120,815] 🔴 -4.0% 86,952 ops/sec [82,864..89,644] → 91,736 ops/sec [91,105..93,193] 🟢 +5.5%
with defaults 174,573 ops/sec [172,644..175,891] → 177,577 ops/sec [175,614..179,335] ~ overlap (+1.7%) 139,369 ops/sec [136,468..141,503] → 150,073 ops/sec [148,988..151,000] 🟢 +7.7%
skip elements 187,936 ops/sec [186,345..188,837] → 189,369 ops/sec [184,895..192,670] ~ overlap (+0.8%) 127,354 ops/sec [126,584..129,238] → 137,449 ops/sec [136,491..137,899] 🟢 +7.9%
nested array destructuring 89,088 ops/sec [87,022..90,510] → 87,325 ops/sec [85,506..90,262] ~ overlap (-2.0%) 42,884 ops/sec [42,316..43,980] → 46,754 ops/sec [46,475..47,038] 🟢 +9.0%
swap variables 221,915 ops/sec [220,566..225,253] → 218,801 ops/sec [214,623..223,623] ~ overlap (-1.4%) 157,796 ops/sec [152,546..159,104] → 168,083 ops/sec [166,909..169,240] 🟢 +6.5%
simple object destructuring 147,365 ops/sec [143,113..149,304] → 148,276 ops/sec [139,237..151,182] ~ overlap (+0.6%) 174,475 ops/sec [168,783..177,808] → 170,263 ops/sec [168,614..182,553] ~ overlap (-2.4%)
with defaults 164,062 ops/sec [162,118..169,066] → 165,675 ops/sec [161,337..167,298] ~ overlap (+1.0%) 228,673 ops/sec [222,984..234,754] → 234,164 ops/sec [230,915..241,295] ~ overlap (+2.4%)
with renaming 158,028 ops/sec [150,698..162,724] → 156,888 ops/sec [151,839..159,562] ~ overlap (-0.7%) 178,307 ops/sec [175,692..179,529] → 179,267 ops/sec [177,787..180,793] ~ overlap (+0.5%)
nested object destructuring 80,491 ops/sec [79,537..81,496] → 78,564 ops/sec [77,462..79,303] 🔴 -2.4% 87,400 ops/sec [87,263..87,916] → 87,796 ops/sec [79,861..89,500] ~ overlap (+0.5%)
rest properties 55,950 ops/sec [55,356..57,263] → 55,709 ops/sec [54,699..57,654] ~ overlap (-0.4%) 78,793 ops/sec [76,386..80,373] → 82,921 ops/sec [79,988..84,738] ~ overlap (+5.2%)
object parameter 45,829 ops/sec [44,246..47,329] → 43,367 ops/sec [41,988..44,465] ~ overlap (-5.4%) 69,666 ops/sec [68,350..71,019] → 73,628 ops/sec [72,332..75,369] 🟢 +5.7%
array parameter 57,281 ops/sec [55,733..58,325] → 54,940 ops/sec [53,729..55,796] ~ overlap (-4.1%) 61,285 ops/sec [60,854..61,669] → 67,362 ops/sec [66,878..67,907] 🟢 +9.9%
mixed destructuring in map 13,017 ops/sec [12,554..13,190] → 12,467 ops/sec [12,224..12,591] ~ overlap (-4.2%) 18,119 ops/sec [17,419..18,673] → 19,270 ops/sec [18,997..19,812] 🟢 +6.4%
forEach with array destructuring 29,525 ops/sec [29,353..29,799] → 28,397 ops/sec [27,490..28,637] 🔴 -3.8% 22,192 ops/sec [21,651..23,126] → 25,422 ops/sec [25,197..25,506] 🟢 +14.6%
map with array destructuring 30,519 ops/sec [30,307..30,688] → 28,935 ops/sec [28,240..29,510] 🔴 -5.2% 21,335 ops/sec [20,600..22,093] → 23,931 ops/sec [23,756..24,184] 🟢 +12.2%
filter with array destructuring 32,024 ops/sec [31,657..32,074] → 30,191 ops/sec [29,159..30,794] 🔴 -5.7% 23,349 ops/sec [22,850..23,785] → 25,594 ops/sec [24,735..25,937] 🟢 +9.6%
reduce with array destructuring 34,030 ops/sec [32,938..34,973] → 31,769 ops/sec [30,766..32,715] 🔴 -6.6% 24,147 ops/sec [23,822..24,588] → 25,743 ops/sec [25,017..26,203] 🟢 +6.6%
map with object destructuring 29,059 ops/sec [28,898..29,402] → 28,249 ops/sec [27,811..28,779] 🔴 -2.8% 41,552 ops/sec [41,123..41,906] → 42,595 ops/sec [42,344..43,995] 🟢 +2.5%
map with nested destructuring 24,039 ops/sec [22,911..24,741] → 23,834 ops/sec [23,570..24,383] ~ overlap (-0.9%) 38,019 ops/sec [37,356..38,879] → 38,937 ops/sec [38,556..40,417] ~ overlap (+2.4%)
map with rest in destructuring 18,247 ops/sec [18,060..18,552] → 18,127 ops/sec [17,420..18,372] ~ overlap (-0.7%) 12,485 ops/sec [12,391..12,638] → 13,282 ops/sec [13,005..13,485] 🟢 +6.4%
map with defaults in destructuring 22,675 ops/sec [22,476..22,844] → 22,128 ops/sec [21,858..22,806] ~ overlap (-2.4%) 31,069 ops/sec [30,748..31,233] → 31,428 ops/sec [30,969..31,856] ~ overlap (+1.2%)
fibonacci.js — Interp: 🔴 7, 1 unch. · avg -4.8% · Bytecode: 🟢 6, 2 unch. · avg +5.7%
Benchmark Interpreted Δ Bytecode Δ
recursive fib(15) 120 ops/sec [117..123] → 113 ops/sec [110..116] 🔴 -5.5% 514 ops/sec [507..518] → 533 ops/sec [521..540] 🟢 +3.8%
recursive fib(20) 11 ops/sec [11..11] → 10 ops/sec [10..10] 🔴 -5.6% 47 ops/sec [46..47] → 48 ops/sec [47..49] 🟢 +2.8%
recursive fib(15) typed 122 ops/sec [120..125] → 116 ops/sec [114..118] 🔴 -4.7% 423 ops/sec [421..428] → 453 ops/sec [446..456] 🟢 +7.1%
recursive fib(20) typed 11 ops/sec [11..11] → 10 ops/sec [10..10] 🔴 -6.6% 38 ops/sec [38..39] → 41 ops/sec [41..41] 🟢 +7.8%
iterative fib(20) via reduce 5,244 ops/sec [5,105..5,288] → 4,942 ops/sec [4,844..4,981] 🔴 -5.7% 9,287 ops/sec [9,198..9,359] → 10,629 ops/sec [9,952..10,751] 🟢 +14.4%
iterator fib(20) 3,999 ops/sec [3,961..4,014] → 3,781 ops/sec [3,717..3,803] 🔴 -5.4% 8,012 ops/sec [7,868..8,056] → 8,261 ops/sec [8,101..8,294] 🟢 +3.1%
iterator fib(20) via Iterator.from + take 6,656 ops/sec [6,526..6,734] → 6,495 ops/sec [6,375..6,521] 🔴 -2.4% 9,280 ops/sec [9,111..9,486] → 9,606 ops/sec [9,294..9,846] ~ overlap (+3.5%)
iterator fib(20) last value via reduce 4,868 ops/sec [4,769..4,940] → 4,745 ops/sec [4,658..4,794] ~ overlap (-2.5%) 6,762 ops/sec [6,622..6,980] → 6,971 ops/sec [6,838..7,132] ~ overlap (+3.1%)
float16array.js — Interp: 🟢 3, 🔴 17, 12 unch. · avg -2.7% · Bytecode: 🟢 18, 🔴 4, 10 unch. · avg +4.8%
Benchmark Interpreted Δ Bytecode Δ
new Float16Array(0) 136,245 ops/sec [134,071..137,741] → 137,298 ops/sec [135,397..139,190] ~ overlap (+0.8%) 160,505 ops/sec [159,422..163,719] → 159,357 ops/sec [155,531..160,629] ~ overlap (-0.7%)
new Float16Array(100) 134,402 ops/sec [133,836..134,807] → 132,821 ops/sec [131,909..133,703] 🔴 -1.2% 156,562 ops/sec [152,076..162,187] → 152,720 ops/sec [150,187..154,945] ~ overlap (-2.5%)
new Float16Array(1000) 112,984 ops/sec [112,297..113,356] → 111,128 ops/sec [110,269..111,336] 🔴 -1.6% 125,540 ops/sec [123,325..125,875] → 132,952 ops/sec [131,715..135,174] 🟢 +5.9%
Float16Array.from([...100]) 88,410 ops/sec [87,683..89,093] → 84,045 ops/sec [83,470..84,201] 🔴 -4.9% 93,937 ops/sec [92,692..95,513] → 91,222 ops/sec [90,501..92,556] 🔴 -2.9%
Float16Array.of(1.5, 2.5, 3.5, 4.5, 5.5) 132,964 ops/sec [131,227..134,245] → 135,224 ops/sec [134,464..135,418] 🟢 +1.7% 112,820 ops/sec [110,171..114,524] → 112,713 ops/sec [110,440..114,918] ~ overlap (-0.1%)
new Float16Array(float64Array) 89,381 ops/sec [87,986..90,662] → 88,444 ops/sec [87,781..88,750] ~ overlap (-1.0%) 101,132 ops/sec [100,250..102,808] → 96,592 ops/sec [95,947..97,585] 🔴 -4.5%
sequential write 100 elements 1,537 ops/sec [1,527..1,545] → 1,505 ops/sec [1,493..1,522] 🔴 -2.0% 3,874 ops/sec [3,848..3,901] → 4,140 ops/sec [4,112..4,174] 🟢 +6.9%
sequential read 100 elements 1,714 ops/sec [1,696..1,734] → 1,669 ops/sec [1,657..1,678] 🔴 -2.6% 4,931 ops/sec [4,691..5,075] → 5,359 ops/sec [5,307..5,393] 🟢 +8.7%
write special values (NaN, Inf, -0) 71,030 ops/sec [70,900..71,830] → 66,614 ops/sec [65,759..67,343] 🔴 -6.2% 120,031 ops/sec [117,494..121,335] → 122,526 ops/sec [119,624..123,687] ~ overlap (+2.1%)
Float16Array write 1,575 ops/sec [1,560..1,597] → 1,502 ops/sec [1,497..1,511] 🔴 -4.6% 3,857 ops/sec [3,778..3,924] → 4,203 ops/sec [4,182..4,210] 🟢 +9.0%
Float32Array write 1,563 ops/sec [1,552..1,598] → 1,497 ops/sec [1,469..1,508] 🔴 -4.2% 3,909 ops/sec [3,856..4,001] → 4,235 ops/sec [4,183..4,296] 🟢 +8.4%
Float64Array write 1,602 ops/sec [1,580..1,605] → 1,510 ops/sec [1,488..1,521] 🔴 -5.7% 3,873 ops/sec [3,813..3,895] → 4,260 ops/sec [4,226..4,287] 🟢 +10.0%
Float16Array read 1,669 ops/sec [1,654..1,677] → 1,608 ops/sec [1,592..1,630] 🔴 -3.6% 4,886 ops/sec [4,851..4,916] → 5,324 ops/sec [5,283..5,385] 🟢 +9.0%
Float32Array read 1,724 ops/sec [1,674..1,768] → 1,702 ops/sec [1,655..1,743] ~ overlap (-1.3%) 5,143 ops/sec [5,097..5,222] → 5,387 ops/sec [5,369..5,453] 🟢 +4.8%
Float64Array read 1,661 ops/sec [1,644..1,663] → 1,721 ops/sec [1,695..1,730] 🟢 +3.6% 5,115 ops/sec [5,053..5,132] → 5,463 ops/sec [5,388..5,516] 🟢 +6.8%
fill(1.5) 23,127 ops/sec [22,851..24,517] → 21,973 ops/sec [21,627..22,423] 🔴 -5.0% 22,785 ops/sec [22,573..23,360] → 23,056 ops/sec [22,560..23,283] ~ overlap (+1.2%)
slice() 86,672 ops/sec [84,648..87,989] → 88,154 ops/sec [84,864..89,558] ~ overlap (+1.7%) 100,778 ops/sec [100,351..101,584] → 94,871 ops/sec [94,155..95,689] 🔴 -5.9%
map(x => x * 2) 2,732 ops/sec [2,716..2,761] → 2,745 ops/sec [2,699..2,772] ~ overlap (+0.5%) 3,709 ops/sec [3,661..3,795] → 3,995 ops/sec [3,905..4,038] 🟢 +7.7%
filter(x => x > 25) 2,938 ops/sec [2,870..2,963] → 2,922 ops/sec [2,912..2,964] ~ overlap (-0.6%) 4,139 ops/sec [4,092..4,156] → 4,354 ops/sec [4,342..4,406] 🟢 +5.2%
reduce (sum) 2,831 ops/sec [2,741..2,877] → 2,788 ops/sec [2,755..2,828] ~ overlap (-1.5%) 3,439 ops/sec [3,413..3,452] → 3,678 ops/sec [3,642..3,690] 🟢 +6.9%
sort() 23,630 ops/sec [23,448..23,766] → 20,890 ops/sec [20,759..21,036] 🔴 -11.6% 20,282 ops/sec [20,125..20,368] → 24,252 ops/sec [24,140..24,319] 🟢 +19.6%
indexOf() 117,648 ops/sec [115,840..117,856] → 109,738 ops/sec [109,198..111,355] 🔴 -6.7% 118,198 ops/sec [117,943..118,937] → 142,105 ops/sec [139,031..143,343] 🟢 +20.2%
reverse() 109,305 ops/sec [108,626..109,546] → 113,505 ops/sec [111,738..114,947] 🟢 +3.8% 132,112 ops/sec [129,945..132,311] → 129,368 ops/sec [127,087..130,079] ~ overlap (-2.1%)
toReversed() 59,214 ops/sec [58,387..59,493] → 54,509 ops/sec [54,337..55,181] 🔴 -7.9% 56,764 ops/sec [56,397..57,184] → 63,877 ops/sec [63,630..64,267] 🟢 +12.5%
toSorted() 926 ops/sec [916..955] → 819 ops/sec [816..822] 🔴 -11.6% 819 ops/sec [812..821] → 935 ops/sec [931..935] 🟢 +14.2%
create view over existing buffer 158,009 ops/sec [153,795..159,986] → 158,297 ops/sec [154,370..160,442] ~ overlap (+0.2%) 189,021 ops/sec [186,959..195,551] → 189,081 ops/sec [182,053..191,051] ~ overlap (+0.0%)
subarray() 198,523 ops/sec [194,120..200,891] → 188,740 ops/sec [184,708..191,033] 🔴 -4.9% 263,881 ops/sec [258,877..268,022] → 260,559 ops/sec [256,949..262,660] ~ overlap (-1.3%)
set() from array 220,999 ops/sec [218,179..223,131] → 212,678 ops/sec [208,008..222,054] ~ overlap (-3.8%) 279,377 ops/sec [278,151..281,066] → 272,391 ops/sec [264,386..273,818] 🔴 -2.5%
for-of loop 2,434 ops/sec [2,422..2,446] → 2,441 ops/sec [2,435..2,450] ~ overlap (+0.3%) 6,888 ops/sec [6,847..6,964] → 7,666 ops/sec [7,586..7,689] 🟢 +11.3%
spread into array 9,094 ops/sec [9,032..9,096] → 8,969 ops/sec [8,815..9,284] ~ overlap (-1.4%) 36,155 ops/sec [36,007..36,543] → 37,138 ops/sec [36,492..37,571] ~ overlap (+2.7%)
f16round(1.337) 270,108 ops/sec [264,342..278,140] → 268,099 ops/sec [267,970..269,358] ~ overlap (-0.7%) 295,447 ops/sec [294,981..298,824] → 295,403 ops/sec [293,034..301,583] ~ overlap (-0.0%)
f16round over 100 values 1,718 ops/sec [1,692..1,730] → 1,657 ops/sec [1,624..1,664] 🔴 -3.5% 3,415 ops/sec [3,321..3,510] → 3,565 ops/sec [3,532..3,580] 🟢 +4.4%
for-of.js — Interp: 7 unch. · avg -1.3% · Bytecode: 🟢 6, 1 unch. · avg +8.4%
Benchmark Interpreted Δ Bytecode Δ
for...of with 10-element array 21,955 ops/sec [21,704..22,088] → 22,064 ops/sec [21,967..22,303] ~ overlap (+0.5%) 85,665 ops/sec [84,359..87,738] → 91,958 ops/sec [91,062..96,428] 🟢 +7.3%
for...of with 100-element array 2,553 ops/sec [2,512..2,581] → 2,555 ops/sec [2,452..2,564] ~ overlap (+0.1%) 10,188 ops/sec [10,042..10,324] → 11,052 ops/sec [10,902..11,390] 🟢 +8.5%
for...of with string (10 chars) 15,634 ops/sec [15,558..15,740] → 15,466 ops/sec [15,340..15,591] ~ overlap (-1.1%) 33,358 ops/sec [32,480..33,882] → 35,578 ops/sec [32,750..36,593] ~ overlap (+6.7%)
for...of with Set (10 elements) 22,635 ops/sec [21,994..23,333] → 21,824 ops/sec [20,852..22,151] ~ overlap (-3.6%) 84,976 ops/sec [83,815..85,945] → 91,922 ops/sec [88,181..94,101] 🟢 +8.2%
for...of with Map entries (10 entries) 14,750 ops/sec [14,473..14,948] → 14,488 ops/sec [14,018..14,791] ~ overlap (-1.8%) 14,997 ops/sec [14,665..15,171] → 16,901 ops/sec [16,825..16,996] 🟢 +12.7%
for...of with destructuring 18,913 ops/sec [18,660..18,999] → 18,614 ops/sec [18,203..19,015] ~ overlap (-1.6%) 19,357 ops/sec [19,129..19,664] → 21,347 ops/sec [20,660..22,037] 🟢 +10.3%
for-await-of with sync array 21,712 ops/sec [21,020..21,970] → 21,319 ops/sec [20,734..21,799] ~ overlap (-1.8%) 16,587 ops/sec [16,070..16,891] → 17,466 ops/sec [17,297..17,860] 🟢 +5.3%
generators.js — Interp: 🔴 3, 1 unch. · avg -5.6% · Bytecode: 🟢 3, 1 unch. · avg +5.3%
Benchmark Interpreted Δ Bytecode Δ
manual next over object generator 969 ops/sec [954..982] → 920 ops/sec [905..956] ~ overlap (-5.1%) 887 ops/sec [869..925] → 898 ops/sec [891..902] ~ overlap (+1.2%)
for...of over object generator 1,588 ops/sec [1,568..1,618] → 1,496 ops/sec [1,487..1,510] 🔴 -5.8% 1,343 ops/sec [1,306..1,360] → 1,428 ops/sec [1,407..1,435] 🟢 +6.4%
yield delegation 1,622 ops/sec [1,590..1,629] → 1,520 ops/sec [1,513..1,527] 🔴 -6.3% 1,326 ops/sec [1,309..1,332] → 1,400 ops/sec [1,393..1,412] 🟢 +5.6%
class generator method 1,595 ops/sec [1,585..1,635] → 1,512 ops/sec [1,504..1,540] 🔴 -5.2% 1,317 ops/sec [1,305..1,322] → 1,422 ops/sec [1,416..1,422] 🟢 +8.0%
iterators.js — Interp: 🟢 2, 🔴 25, 15 unch. · avg -3.3% · Bytecode: 🟢 28, 🔴 1, 13 unch. · avg +6.2%
Benchmark Interpreted Δ Bytecode Δ
Iterator.from({next}).toArray() — 20 elements 5,833 ops/sec [5,785..5,949] → 5,781 ops/sec [5,596..6,034] ~ overlap (-0.9%) 9,062 ops/sec [8,994..9,124] → 9,536 ops/sec [9,258..9,638] 🟢 +5.2%
Iterator.from({next}).toArray() — 50 elements 2,481 ops/sec [2,461..2,511] → 2,519 ops/sec [2,481..2,571] ~ overlap (+1.5%) 4,150 ops/sec [4,073..4,176] → 4,163 ops/sec [4,086..4,178] ~ overlap (+0.3%)
spread pre-wrapped iterator — 20 elements 4,891 ops/sec [4,822..4,928] → 4,767 ops/sec [4,709..4,791] 🔴 -2.5% 8,960 ops/sec [8,949..8,989] → 9,222 ops/sec [9,136..9,295] 🟢 +2.9%
Iterator.from({next}).forEach — 50 elements 1,723 ops/sec [1,707..1,741] → 1,715 ops/sec [1,685..1,726] ~ overlap (-0.4%) 2,742 ops/sec [2,680..2,771] → 2,807 ops/sec [2,798..2,818] 🟢 +2.4%
Iterator.from({next}).reduce — 50 elements 1,788 ops/sec [1,761..1,814] → 1,718 ops/sec [1,705..1,736] 🔴 -3.9% 2,707 ops/sec [2,572..2,855] → 2,781 ops/sec [2,715..2,812] ~ overlap (+2.7%)
wrap array iterator 80,340 ops/sec [78,268..80,992] → 78,260 ops/sec [73,997..78,985] ~ overlap (-2.6%) 82,704 ops/sec [82,553..83,102] → 85,124 ops/sec [83,274..86,962] 🟢 +2.9%
wrap plain {next()} object 4,130 ops/sec [4,057..4,138] → 4,107 ops/sec [4,055..4,113] ~ overlap (-0.5%) 6,665 ops/sec [6,601..6,716] → 6,966 ops/sec [6,601..7,032] ~ overlap (+4.5%)
map + toArray (50 elements) 1,754 ops/sec [1,750..1,774] → 1,782 ops/sec [1,758..1,785] ~ overlap (+1.6%) 2,891 ops/sec [2,889..2,898] → 2,806 ops/sec [2,775..2,911] ~ overlap (-2.9%)
filter + toArray (50 elements) 1,732 ops/sec [1,704..1,738] → 1,780 ops/sec [1,771..1,842] 🟢 +2.8% 2,838 ops/sec [2,800..2,854] → 2,812 ops/sec [2,707..2,833] ~ overlap (-0.9%)
take(10) + toArray (50 element source) 11,254 ops/sec [11,014..11,416] → 11,533 ops/sec [11,462..11,721] 🟢 +2.5% 18,339 ops/sec [18,237..18,423] → 17,168 ops/sec [16,901..17,554] 🔴 -6.4%
drop(40) + toArray (50 element source) 2,558 ops/sec [2,518..2,575] → 2,694 ops/sec [2,458..2,727] ~ overlap (+5.3%) 4,280 ops/sec [4,260..4,290] → 4,456 ops/sec [4,165..4,518] ~ overlap (+4.1%)
chained map + filter + take (100 element source) 3,300 ops/sec [3,267..3,326] → 3,223 ops/sec [3,142..3,247] 🔴 -2.3% 5,182 ops/sec [5,143..5,306] → 5,278 ops/sec [5,154..5,360] ~ overlap (+1.9%)
some + every (50 elements) 1,015 ops/sec [1,009..1,066] → 1,030 ops/sec [1,014..1,043] ~ overlap (+1.4%) 1,725 ops/sec [1,702..1,733] → 1,707 ops/sec [1,689..1,715] ~ overlap (-1.0%)
find (50 elements) 2,335 ops/sec [2,314..2,341] → 2,259 ops/sec [2,218..2,288] 🔴 -3.2% 3,869 ops/sec [3,836..3,870] → 3,815 ops/sec [3,793..3,843] ~ overlap (-1.4%)
concat 2 arrays (10 + 10 elements) 78,540 ops/sec [77,786..79,279] → 72,403 ops/sec [70,247..72,751] 🔴 -7.8% 74,959 ops/sec [74,611..76,216] → 83,847 ops/sec [83,273..84,702] 🟢 +11.9%
concat 5 arrays (10 elements each) 45,797 ops/sec [43,853..46,546] → 42,484 ops/sec [41,796..42,884] 🔴 -7.2% 44,197 ops/sec [43,734..44,477] → 49,865 ops/sec [47,311..50,438] 🟢 +12.8%
concat 2 arrays (20 + 20 elements) 65,448 ops/sec [64,051..66,985] → 62,519 ops/sec [61,485..63,861] 🔴 -4.5% 66,766 ops/sec [65,997..68,722] → 68,195 ops/sec [67,430..69,311] ~ overlap (+2.1%)
concat + filter + toArray (20 + 20 elements) 6,359 ops/sec [6,112..6,531] → 6,251 ops/sec [6,173..6,433] ~ overlap (-1.7%) 10,060 ops/sec [10,039..10,106] → 9,851 ops/sec [9,649..10,122] ~ overlap (-2.1%)
concat + map + take (20 + 20 elements, take 10) 20,134 ops/sec [19,883..20,505] → 19,809 ops/sec [19,592..20,109] ~ overlap (-1.6%) 28,073 ops/sec [26,749..28,324] → 27,758 ops/sec [26,970..28,921] ~ overlap (-1.1%)
concat Sets (15 + 15 elements) 72,689 ops/sec [71,547..72,705] → 71,309 ops/sec [69,574..72,808] ~ overlap (-1.9%) 74,256 ops/sec [73,264..75,075] → 73,726 ops/sec [73,182..74,065] ~ overlap (-0.7%)
concat strings (13 + 13 characters) 50,183 ops/sec [50,037..50,414] → 49,759 ops/sec [48,820..50,095] ~ overlap (-0.8%) 48,975 ops/sec [48,474..49,232] → 51,604 ops/sec [50,492..51,950] 🟢 +5.4%
zip 2 arrays (10 + 10 elements) 30,895 ops/sec [30,071..31,316] → 29,231 ops/sec [28,280..30,604] ~ overlap (-5.4%) 28,067 ops/sec [28,065..28,242] → 32,226 ops/sec [31,615..32,443] 🟢 +14.8%
zip 3 arrays (10 elements each) 27,993 ops/sec [27,282..28,352] → 27,016 ops/sec [26,561..27,172] 🔴 -3.5% 26,511 ops/sec [26,082..26,603] → 29,118 ops/sec [28,541..29,969] 🟢 +9.8%
zip 2 arrays (20 + 20 elements) 20,123 ops/sec [19,816..20,345] → 19,194 ops/sec [18,747..20,097] ~ overlap (-4.6%) 18,394 ops/sec [17,967..18,990] → 20,830 ops/sec [20,610..21,142] 🟢 +13.2%
zip 2 arrays (50 + 50 elements) 10,218 ops/sec [9,948..10,293] → 9,513 ops/sec [9,250..9,750] 🔴 -6.9% 9,181 ops/sec [8,953..9,291] → 10,577 ops/sec [10,516..10,656] 🟢 +15.2%
zip shortest mode (20 + 10 elements) 30,351 ops/sec [29,195..30,617] → 28,277 ops/sec [27,570..28,561] 🔴 -6.8% 27,768 ops/sec [27,476..28,244] → 31,361 ops/sec [30,549..32,150] 🟢 +12.9%
zip longest mode (10 + 20 elements) 18,050 ops/sec [17,989..18,250] → 16,689 ops/sec [16,636..16,962] 🔴 -7.5% 16,398 ops/sec [16,172..16,435] → 18,576 ops/sec [18,418..18,839] 🟢 +13.3%
zip strict mode (20 + 20 elements) 19,305 ops/sec [19,027..19,458] → 18,084 ops/sec [17,847..18,179] 🔴 -6.3% 17,447 ops/sec [17,082..17,668] → 19,522 ops/sec [19,379..19,681] 🟢 +11.9%
zip + map + toArray (20 + 20 elements) 7,909 ops/sec [7,820..7,953] → 7,591 ops/sec [7,518..7,635] 🔴 -4.0% 5,533 ops/sec [5,497..5,560] → 6,277 ops/sec [6,174..6,426] 🟢 +13.4%
zip + filter + toArray (20 + 20 elements) 7,564 ops/sec [7,541..7,676] → 7,296 ops/sec [7,194..7,330] 🔴 -3.5% 5,631 ops/sec [5,568..5,681] → 6,273 ops/sec [6,139..6,299] 🟢 +11.4%
zip Sets (15 + 15 elements) 24,855 ops/sec [24,701..25,237] → 23,354 ops/sec [23,176..23,394] 🔴 -6.0% 22,752 ops/sec [22,430..23,111] → 25,633 ops/sec [25,509..25,724] 🟢 +12.7%
zipKeyed 2 keys (10 elements each) 31,100 ops/sec [30,884..31,226] → 28,487 ops/sec [27,894..28,819] 🔴 -8.4% 28,940 ops/sec [28,720..29,348] → 31,675 ops/sec [31,458..31,750] 🟢 +9.5%
zipKeyed 3 keys (20 elements each) 15,380 ops/sec [15,105..15,729] → 14,630 ops/sec [14,380..15,069] 🔴 -4.9% 14,563 ops/sec [14,491..14,703] → 15,381 ops/sec [15,204..15,656] 🟢 +5.6%
zipKeyed longest mode (10 + 20 elements) 17,855 ops/sec [17,414..18,039] → 16,869 ops/sec [16,679..17,311] 🔴 -5.5% 16,541 ops/sec [15,994..16,910] → 17,700 ops/sec [17,588..17,894] 🟢 +7.0%
zipKeyed strict mode (20 + 20 elements) 18,875 ops/sec [18,720..19,157] → 17,593 ops/sec [17,182..17,940] 🔴 -6.8% 17,523 ops/sec [17,114..18,085] → 18,955 ops/sec [18,879..19,005] 🟢 +8.2%
zipKeyed + filter + map (20 elements) 5,778 ops/sec [5,749..5,819] → 5,606 ops/sec [5,484..5,616] 🔴 -3.0% 7,009 ops/sec [6,872..7,098] → 7,639 ops/sec [7,426..7,663] 🟢 +9.0%
array.values().map().filter().toArray() 3,034 ops/sec [3,008..3,047] → 2,942 ops/sec [2,900..2,979] 🔴 -3.0% 4,679 ops/sec [4,440..4,733] → 4,851 ops/sec [4,790..4,870] 🟢 +3.7%
array.values().take(5).toArray() 102,411 ops/sec [101,434..102,473] → 96,707 ops/sec [94,227..99,941] 🔴 -5.6% 111,750 ops/sec [109,422..112,704] → 121,905 ops/sec [121,479..123,851] 🟢 +9.1%
array.values().drop(45).toArray() 83,462 ops/sec [83,042..83,898] → 76,734 ops/sec [75,197..78,198] 🔴 -8.1% 88,401 ops/sec [87,549..89,827] → 97,924 ops/sec [95,853..98,545] 🟢 +10.8%
map.entries() chained helpers 4,428 ops/sec [4,392..4,486] → 4,214 ops/sec [4,163..4,395] ~ overlap (-4.8%) 2,980 ops/sec [2,912..3,003] → 3,247 ops/sec [3,232..3,252] 🟢 +9.0%
set.values() chained helpers 6,633 ops/sec [6,591..6,757] → 6,480 ops/sec [6,421..6,555] 🔴 -2.3% 9,956 ops/sec [9,709..10,152] → 10,405 ops/sec [10,253..10,640] 🟢 +4.5%
string iterator map + toArray 5,668 ops/sec [5,541..5,724] → 5,405 ops/sec [5,346..5,485] 🔴 -4.6% 6,093 ops/sec [5,940..6,153] → 6,885 ops/sec [6,821..6,944] 🟢 +13.0%
json.js — Interp: 🔴 5, 15 unch. · avg -1.8% · Bytecode: 🟢 3, 🔴 5, 12 unch. · avg -0.6%
Benchmark Interpreted Δ Bytecode Δ
parse simple object 72,256 ops/sec [71,241..73,788] → 72,730 ops/sec [70,539..73,606] ~ overlap (+0.7%) 74,656 ops/sec [73,737..75,670] → 74,216 ops/sec [73,760..74,738] ~ overlap (-0.6%)
parse nested object 48,953 ops/sec [47,112..49,876] → 48,297 ops/sec [47,039..48,964] ~ overlap (-1.3%) 48,923 ops/sec [48,564..49,452] → 47,393 ops/sec [47,133..47,685] 🔴 -3.1%
parse array of objects 29,448 ops/sec [29,119..29,709] → 28,944 ops/sec [28,128..30,601] ~ overlap (-1.7%) 28,946 ops/sec [28,724..30,123] → 28,997 ops/sec [28,534..29,308] ~ overlap (+0.2%)
parse large flat object 31,267 ops/sec [30,347..31,609] → 30,906 ops/sec [29,914..30,951] ~ overlap (-1.2%) 30,495 ops/sec [29,424..30,773] → 30,390 ops/sec [30,185..30,521] ~ overlap (-0.3%)
parse mixed types 36,304 ops/sec [35,201..37,335] → 35,827 ops/sec [35,109..36,114] ~ overlap (-1.3%) 36,748 ops/sec [36,402..36,871] → 36,610 ops/sec [35,886..37,130] ~ overlap (-0.4%)
stringify simple object 80,015 ops/sec [76,763..83,937] → 77,129 ops/sec [74,952..80,532] ~ overlap (-3.6%) 79,038 ops/sec [78,623..79,595] → 75,935 ops/sec [75,348..76,342] 🔴 -3.9%
stringify nested object 47,332 ops/sec [47,144..47,703] → 44,921 ops/sec [44,419..47,402] ~ overlap (-5.1%) 43,632 ops/sec [42,699..44,223] → 43,332 ops/sec [41,912..43,794] ~ overlap (-0.7%)
stringify array of objects 19,656 ops/sec [19,411..19,964] → 19,040 ops/sec [18,354..19,234] 🔴 -3.1% 19,126 ops/sec [19,089..19,216] → 19,711 ops/sec [19,267..19,854] 🟢 +3.1%
stringify mixed types 30,219 ops/sec [29,852..30,543] → 29,792 ops/sec [28,890..30,331] ~ overlap (-1.4%) 28,396 ops/sec [27,865..28,978] → 28,332 ops/sec [28,164..28,610] ~ overlap (-0.2%)
reviver doubles numbers 14,563 ops/sec [14,327..14,875] → 14,637 ops/sec [14,285..14,719] ~ overlap (+0.5%) 18,631 ops/sec [18,331..18,730] → 18,028 ops/sec [17,774..18,082] 🔴 -3.2%
reviver filters properties 12,781 ops/sec [12,702..12,888] → 11,750 ops/sec [11,618..12,168] 🔴 -8.1% 16,284 ops/sec [16,063..16,465] → 16,166 ops/sec [15,990..16,290] ~ overlap (-0.7%)
reviver on nested object 16,956 ops/sec [16,687..17,561] → 16,386 ops/sec [16,221..16,696] ~ overlap (-3.4%) 19,872 ops/sec [19,635..20,457] → 19,427 ops/sec [19,379..19,814] ~ overlap (-2.2%)
reviver on array 8,694 ops/sec [8,665..8,724] → 8,808 ops/sec [8,653..8,851] ~ overlap (+1.3%) 11,121 ops/sec [10,878..11,292] → 11,241 ops/sec [11,078..11,412] ~ overlap (+1.1%)
replacer function doubles numbers 16,624 ops/sec [16,507..16,764] → 16,718 ops/sec [16,164..16,894] ~ overlap (+0.6%) 22,122 ops/sec [22,028..22,493] → 21,623 ops/sec [21,465..21,713] 🔴 -2.3%
replacer function excludes properties 21,694 ops/sec [21,354..22,240] → 22,009 ops/sec [21,309..22,386] ~ overlap (+1.4%) 26,764 ops/sec [26,456..27,358] → 26,307 ops/sec [26,135..26,701] ~ overlap (-1.7%)
array replacer (allowlist) 49,150 ops/sec [48,934..50,279] → 49,256 ops/sec [47,574..50,255] ~ overlap (+0.2%) 47,248 ops/sec [46,701..48,071] → 45,853 ops/sec [45,409..46,126] 🔴 -3.0%
stringify with 2-space indent 39,794 ops/sec [39,591..40,371] → 38,472 ops/sec [38,116..38,654] 🔴 -3.3% 39,196 ops/sec [38,614..39,537] → 40,023 ops/sec [39,851..40,464] 🟢 +2.1%
stringify with tab indent 40,668 ops/sec [40,425..42,193] → 39,132 ops/sec [38,129..39,319] 🔴 -3.8% 38,667 ops/sec [38,504..38,831] → 39,603 ops/sec [39,271..39,822] 🟢 +2.4%
parse then stringify 23,774 ops/sec [23,657..23,925] → 23,203 ops/sec [23,055..23,295] 🔴 -2.4% 24,848 ops/sec [24,471..25,265] → 24,912 ops/sec [24,634..25,272] ~ overlap (+0.3%)
stringify then parse 13,874 ops/sec [13,666..14,224] → 13,705 ops/sec [13,602..13,875] ~ overlap (-1.2%) 14,372 ops/sec [13,988..14,591] → 14,645 ops/sec [14,423..14,792] ~ overlap (+1.9%)
jsx.jsx — Interp: 🔴 19, 2 unch. · avg -5.2% · Bytecode: 🟢 13, 8 unch. · avg +4.9%
Benchmark Interpreted Δ Bytecode Δ
simple element 99,327 ops/sec [97,632..100,657] → 99,340 ops/sec [99,008..99,890] ~ overlap (+0.0%) 144,722 ops/sec [143,056..146,151] → 151,602 ops/sec [149,118..157,537] 🟢 +4.8%
self-closing element 102,343 ops/sec [101,372..103,960] → 98,316 ops/sec [96,375..100,387] 🔴 -3.9% 162,129 ops/sec [155,462..166,272] → 170,708 ops/sec [162,542..176,709] ~ overlap (+5.3%)
element with string attribute 86,475 ops/sec [85,535..86,896] → 83,764 ops/sec [82,148..84,763] 🔴 -3.1% 114,719 ops/sec [111,358..121,713] → 122,216 ops/sec [115,919..124,134] ~ overlap (+6.5%)
element with multiple attributes 75,434 ops/sec [72,498..76,576] → 72,631 ops/sec [71,463..73,965] ~ overlap (-3.7%) 85,950 ops/sec [85,401..89,403] → 91,762 ops/sec [90,114..95,132] 🟢 +6.8%
element with expression attribute 79,966 ops/sec [79,555..80,279] → 75,894 ops/sec [75,202..76,822] 🔴 -5.1% 116,708 ops/sec [114,747..117,944] → 122,555 ops/sec [119,842..124,171] 🟢 +5.0%
text child 99,701 ops/sec [98,834..101,425] → 93,734 ops/sec [93,632..94,522] 🔴 -6.0% 139,812 ops/sec [138,057..144,766] → 147,057 ops/sec [145,984..156,031] 🟢 +5.2%
expression child 97,313 ops/sec [96,361..97,471] → 93,786 ops/sec [90,034..95,143] 🔴 -3.6% 139,643 ops/sec [139,154..140,821] → 147,992 ops/sec [145,391..151,923] 🟢 +6.0%
mixed text and expression 91,969 ops/sec [91,328..92,562] → 86,972 ops/sec [84,745..87,662] 🔴 -5.4% 123,462 ops/sec [118,827..125,884] → 123,028 ops/sec [117,145..126,170] ~ overlap (-0.4%)
nested elements (3 levels) 38,748 ops/sec [37,989..38,986] → 36,924 ops/sec [35,985..37,693] 🔴 -4.7% 54,241 ops/sec [52,812..54,686] → 55,299 ops/sec [53,887..56,309] ~ overlap (+2.0%)
sibling children 28,782 ops/sec [28,636..29,211] → 27,351 ops/sec [26,911..27,390] 🔴 -5.0% 39,265 ops/sec [38,806..40,987] → 40,683 ops/sec [40,193..42,528] ~ overlap (+3.6%)
component element 75,662 ops/sec [73,732..79,008] → 72,127 ops/sec [71,111..72,458] 🔴 -4.7% 103,598 ops/sec [101,161..106,898] → 115,048 ops/sec [111,737..117,915] 🟢 +11.1%
component with children 46,910 ops/sec [45,223..47,880] → 44,239 ops/sec [43,337..44,395] 🔴 -5.7% 63,222 ops/sec [62,162..63,659] → 68,529 ops/sec [68,169..69,468] 🟢 +8.4%
dotted component 66,955 ops/sec [65,745..71,113] → 62,078 ops/sec [61,547..62,649] 🔴 -7.3% 81,797 ops/sec [81,421..82,239] → 89,174 ops/sec [85,513..91,481] 🟢 +9.0%
empty fragment 105,290 ops/sec [104,102..106,996] → 98,585 ops/sec [97,776..98,977] 🔴 -6.4% 173,950 ops/sec [167,442..177,458] → 187,377 ops/sec [183,503..189,754] 🟢 +7.7%
fragment with children 29,134 ops/sec [28,778..30,390] → 27,197 ops/sec [27,125..27,747] 🔴 -6.6% 39,807 ops/sec [39,521..39,982] → 43,536 ops/sec [41,434..43,947] 🟢 +9.4%
spread attributes 56,753 ops/sec [56,551..56,839] → 52,607 ops/sec [52,507..52,755] 🔴 -7.3% 59,417 ops/sec [58,381..60,135] → 61,866 ops/sec [61,423..62,430] 🟢 +4.1%
spread with overrides 50,676 ops/sec [50,433..50,959] → 47,247 ops/sec [46,204..47,641] 🔴 -6.8% 52,513 ops/sec [51,747..52,543] → 54,722 ops/sec [53,615..55,056] 🟢 +4.2%
shorthand props 79,505 ops/sec [78,430..81,673] → 75,070 ops/sec [73,293..75,850] 🔴 -5.6% 107,028 ops/sec [106,133..108,885] → 107,368 ops/sec [105,716..108,988] ~ overlap (+0.3%)
nav bar structure 14,057 ops/sec [13,713..14,360] → 13,273 ops/sec [13,068..13,536] 🔴 -5.6% 18,536 ops/sec [18,411..18,877] → 19,008 ops/sec [18,536..19,238] ~ overlap (+2.5%)
card component tree 16,894 ops/sec [16,586..17,110] → 15,361 ops/sec [14,953..15,564] 🔴 -9.1% 20,776 ops/sec [20,683..20,949] → 20,659 ops/sec [20,406..21,307] ~ overlap (-0.6%)
10 list items via Array.from 7,166 ops/sec [7,116..7,200] → 6,831 ops/sec [6,779..7,012] 🔴 -4.7% 9,150 ops/sec [9,060..9,204] → 9,378 ops/sec [9,329..9,447] 🟢 +2.5%
modules.js — Interp: 🟢 1, 🔴 2, 6 unch. · avg -0.9% · Bytecode: 🟢 5, 4 unch. · avg +3.6%
Benchmark Interpreted Δ Bytecode Δ
call imported function 167,595 ops/sec [163,768..168,876] → 164,425 ops/sec [161,719..165,320] ~ overlap (-1.9%) 697,169 ops/sec [687,259..703,455] → 704,036 ops/sec [692,552..710,618] ~ overlap (+1.0%)
call two imported functions 94,998 ops/sec [93,056..95,745] → 92,902 ops/sec [90,696..96,457] ~ overlap (-2.2%) 445,671 ops/sec [443,931..447,553] → 451,061 ops/sec [445,284..459,600] ~ overlap (+1.2%)
read imported constant 541,165 ops/sec [533,362..544,804] → 552,304 ops/sec [546,633..556,928] 🟢 +2.1% 1,794,319 ops/sec [1,771,082..1,801,229] → 1,874,798 ops/sec [1,856,827..1,901,349] 🟢 +4.5%
read imported string 532,483 ops/sec [525,591..547,847] → 539,921 ops/sec [519,778..547,416] ~ overlap (+1.4%) 1,798,909 ops/sec [1,791,674..1,800,627] → 1,861,838 ops/sec [1,851,212..1,865,313] 🟢 +3.5%
read JSON string property 545,796 ops/sec [536,469..559,629] → 537,986 ops/sec [527,079..539,312] ~ overlap (-1.4%) 1,765,341 ops/sec [1,752,659..1,768,958] → 1,894,546 ops/sec [1,876,821..1,917,920] 🟢 +7.3%
read JSON number property 544,854 ops/sec [532,729..548,851] → 524,557 ops/sec [520,460..532,263] 🔴 -3.7% 1,762,535 ops/sec [1,759,456..1,769,202] → 1,882,260 ops/sec [1,834,239..1,898,711] 🟢 +6.8%
read JSON boolean property 562,619 ops/sec [551,982..568,547] → 542,399 ops/sec [506,991..550,627] 🔴 -3.6% 1,769,427 ops/sec [1,743,449..1,783,487] → 1,820,744 ops/sec [1,792,258..1,834,421] 🟢 +2.9%
read JSON array property 552,813 ops/sec [543,199..569,583] → 548,662 ops/sec [530,775..550,594] ~ overlap (-0.8%) 1,751,684 ops/sec [1,748,840..1,754,372] → 1,812,340 ops/sec [1,721,146..1,830,084] ~ overlap (+3.5%)
read multiple JSON properties 329,701 ops/sec [326,010..339,035] → 337,107 ops/sec [333,246..337,486] ~ overlap (+2.2%) 1,450,452 ops/sec [1,419,259..1,485,041] → 1,478,748 ops/sec [1,401,783..1,502,566] ~ overlap (+2.0%)
numbers.js — Interp: 🟢 1, 🔴 1, 9 unch. · avg -1.0% · Bytecode: 🟢 2, 🔴 5, 4 unch. · avg +1.2%
Benchmark Interpreted Δ Bytecode Δ
integer arithmetic 183,606 ops/sec [183,261..184,089] → 181,867 ops/sec [180,671..185,235] ~ overlap (-0.9%) 640,445 ops/sec [630,310..655,058] → 681,051 ops/sec [673,410..690,178] 🟢 +6.3%
floating point arithmetic 205,829 ops/sec [202,435..207,583] → 213,040 ops/sec [211,293..216,475] 🟢 +3.5% 368,072 ops/sec [364,998..370,606] → 452,073 ops/sec [448,650..453,665] 🟢 +22.8%
number coercion 77,265 ops/sec [76,467..78,310] → 77,085 ops/sec [76,875..77,656] ~ overlap (-0.2%) 89,675 ops/sec [87,986..94,143] → 93,279 ops/sec [90,613..94,686] ~ overlap (+4.0%)
toFixed 52,404 ops/sec [52,050..52,654] → 51,619 ops/sec [51,300..52,440] ~ overlap (-1.5%) 57,871 ops/sec [56,919..60,222] → 55,950 ops/sec [55,480..56,032] 🔴 -3.3%
toString 68,094 ops/sec [66,994..69,336] → 67,504 ops/sec [65,564..69,357] ~ overlap (-0.9%) 80,554 ops/sec [79,977..81,838] → 79,326 ops/sec [78,703..79,763] 🔴 -1.5%
valueOf 102,497 ops/sec [101,765..102,845] → 103,701 ops/sec [100,951..107,035] ~ overlap (+1.2%) 123,703 ops/sec [119,861..125,076] → 120,450 ops/sec [120,112..121,346] ~ overlap (-2.6%)
toPrecision 42,573 ops/sec [41,705..43,110] → 43,213 ops/sec [42,674..43,624] ~ overlap (+1.5%) 47,146 ops/sec [46,092..49,465] → 45,702 ops/sec [45,590..46,076] 🔴 -3.1%
Number.isNaN 125,134 ops/sec [123,540..127,194] → 121,417 ops/sec [118,268..126,724] ~ overlap (-3.0%) 127,325 ops/sec [123,669..128,774] → 121,183 ops/sec [120,920..121,653] 🔴 -4.8%
Number.isFinite 124,035 ops/sec [122,283..126,249] → 119,354 ops/sec [119,079..121,546] 🔴 -3.8% 122,731 ops/sec [119,238..126,589] → 116,692 ops/sec [115,950..117,566] 🔴 -4.9%
Number.isInteger 126,980 ops/sec [122,303..129,344] → 122,307 ops/sec [119,720..127,393] ~ overlap (-3.7%) 132,092 ops/sec [126,408..136,196] → 129,058 ops/sec [128,437..129,994] ~ overlap (-2.3%)
Number.parseInt and parseFloat 104,015 ops/sec [101,832..109,041] → 100,567 ops/sec [99,375..106,103] ~ overlap (-3.3%) 99,046 ops/sec [98,135..104,497] → 101,932 ops/sec [98,261..105,015] ~ overlap (+2.9%)
objects.js — Interp: 🔴 4, 3 unch. · avg -3.2% · Bytecode: 🟢 1, 🔴 3, 3 unch. · avg -0.3%
Benchmark Interpreted Δ Bytecode Δ
create simple object 218,015 ops/sec [213,403..220,248] → 214,447 ops/sec [203,972..215,861] ~ overlap (-1.6%) 262,750 ops/sec [261,459..265,324] → 253,912 ops/sec [250,905..256,126] 🔴 -3.4%
create nested object 116,843 ops/sec [115,927..117,354] → 112,415 ops/sec [110,296..114,168] 🔴 -3.8% 113,537 ops/sec [112,517..114,411] → 110,329 ops/sec [110,050..110,768] 🔴 -2.8%
create 50 objects via Array.from 4,330 ops/sec [4,213..4,427] → 4,101 ops/sec [4,022..4,165] 🔴 -5.3% 4,598 ops/sec [4,554..4,620] → 4,580 ops/sec [4,498..4,642] ~ overlap (-0.4%)
property read 203,172 ops/sec [200,185..208,578] → 202,916 ops/sec [200,488..205,838] ~ overlap (-0.1%) 301,060 ops/sec [300,871..301,490] → 298,879 ops/sec [296,631..300,801] 🔴 -0.7%
Object.keys 125,187 ops/sec [122,332..126,922] → 120,975 ops/sec [119,377..124,570] ~ overlap (-3.4%) 139,640 ops/sec [138,054..140,602] → 138,658 ops/sec [137,920..139,383] ~ overlap (-0.7%)
Object.entries 51,359 ops/sec [50,169..52,187] → 49,593 ops/sec [48,979..49,791] 🔴 -3.4% 52,066 ops/sec [51,437..52,205] → 54,419 ops/sec [53,826..54,959] 🟢 +4.5%
spread operator 92,278 ops/sec [91,841..95,725] → 88,157 ops/sec [87,863..88,427] 🔴 -4.5% 98,953 ops/sec [96,390..102,440] → 100,632 ops/sec [98,533..101,798] ~ overlap (+1.7%)
promises.js — Interp: 🔴 10, 2 unch. · avg -7.4% · Bytecode: 🟢 6, 6 unch. · avg +3.9%
Benchmark Interpreted Δ Bytecode Δ
Promise.resolve(value) 225,656 ops/sec [220,009..229,899] → 217,022 ops/sec [212,977..218,457] 🔴 -3.8% 248,791 ops/sec [245,311..259,125] → 259,942 ops/sec [255,490..266,454] ~ overlap (+4.5%)
new Promise(resolve => resolve(value)) 87,037 ops/sec [85,252..88,154] → 83,273 ops/sec [82,027..84,561] 🔴 -4.3% 107,933 ops/sec [106,777..109,520] → 116,017 ops/sec [115,432..116,379] 🟢 +7.5%
Promise.reject(reason) 231,641 ops/sec [227,060..234,636] → 223,703 ops/sec [212,919..230,808] ~ overlap (-3.4%) 243,197 ops/sec [238,117..247,938] → 246,545 ops/sec [244,900..247,281] ~ overlap (+1.4%)
resolve + then (1 handler) 83,537 ops/sec [81,371..84,385] → 79,435 ops/sec [77,719..80,177] 🔴 -4.9% 103,451 ops/sec [101,769..104,481] → 102,427 ops/sec [101,751..102,607] ~ overlap (-1.0%)
resolve + then chain (3 deep) 35,240 ops/sec [34,407..35,476] → 31,383 ops/sec [30,777..32,645] 🔴 -10.9% 40,970 ops/sec [40,751..43,116] → 41,914 ops/sec [41,010..43,274] ~ overlap (+2.3%)
resolve + then chain (10 deep) 11,325 ops/sec [11,065..11,420] → 10,503 ops/sec [10,267..11,294] ~ overlap (-7.3%) 13,370 ops/sec [13,183..13,675] → 13,819 ops/sec [13,544..14,084] ~ overlap (+3.4%)
reject + catch + then 50,425 ops/sec [49,510..51,810] → 46,620 ops/sec [45,382..47,834] 🔴 -7.5% 55,140 ops/sec [54,533..56,027] → 56,101 ops/sec [55,745..57,070] ~ overlap (+1.7%)
resolve + finally + then 43,764 ops/sec [42,114..44,064] → 39,957 ops/sec [38,866..40,382] 🔴 -8.7% 46,244 ops/sec [45,845..46,710] → 48,564 ops/sec [48,073..49,024] 🟢 +5.0%
Promise.all (5 resolved) 17,530 ops/sec [17,417..17,784] → 16,364 ops/sec [15,585..16,547] 🔴 -6.7% 16,450 ops/sec [16,119..16,537] → 17,009 ops/sec [16,762..17,208] 🟢 +3.4%
Promise.race (5 resolved) 18,707 ops/sec [18,397..19,050] → 17,007 ops/sec [16,600..17,150] 🔴 -9.1% 17,108 ops/sec [17,039..17,509] → 17,819 ops/sec [17,726..18,017] 🟢 +4.2%
Promise.allSettled (5 mixed) 15,385 ops/sec [15,324..15,503] → 13,813 ops/sec [13,530..13,851] 🔴 -10.2% 13,802 ops/sec [13,682..14,109] → 14,506 ops/sec [14,348..14,742] 🟢 +5.1%
Promise.any (5 mixed) 18,131 ops/sec [17,120..18,284] → 16,056 ops/sec [15,756..16,311] 🔴 -11.4% 15,880 ops/sec [15,689..16,138] → 17,294 ops/sec [16,659..17,756] 🟢 +8.9%
regexp.js — Interp: 🟢 3, 🔴 1, 7 unch. · avg +1.0% · Bytecode: 🟢 1, 🔴 6, 4 unch. · avg -4.9%
Benchmark Interpreted Δ Bytecode Δ
regex literal creation 68,546 ops/sec [68,391..69,055] → 69,854 ops/sec [68,921..72,505] ~ overlap (+1.9%) 65,619 ops/sec [64,800..65,967] → 61,646 ops/sec [60,479..63,370] 🔴 -6.1%
new RegExp(pattern, flags) 61,322 ops/sec [60,609..61,558] → 60,756 ops/sec [59,151..62,773] ~ overlap (-0.9%) 65,370 ops/sec [64,613..66,376] → 61,927 ops/sec [60,865..64,634] ~ overlap (-5.3%)
RegExp(existingRegex) returns the same regex 278,626 ops/sec [270,383..289,040] → 263,193 ops/sec [260,853..266,360] 🔴 -5.5% 402,757 ops/sec [397,011..405,894] → 413,598 ops/sec [408,549..426,027] 🟢 +2.7%
test() on a global regex 65,647 ops/sec [64,271..66,607] → 67,558 ops/sec [67,073..67,926] 🟢 +2.9% 78,738 ops/sec [77,361..83,160] → 72,286 ops/sec [71,880..72,617] 🔴 -8.2%
exec() with capture groups 56,721 ops/sec [56,323..57,441] → 56,196 ops/sec [55,104..58,820] ~ overlap (-0.9%) 66,047 ops/sec [64,613..66,680] → 61,848 ops/sec [56,584..65,092] ~ overlap (-6.4%)
toString() 199,244 ops/sec [195,400..201,468] → 196,430 ops/sec [191,362..201,918] ~ overlap (-1.4%) 286,313 ops/sec [281,931..292,389] → 279,843 ops/sec [274,936..284,366] ~ overlap (-2.3%)
match() with global regex 19,167 ops/sec [18,997..19,331] → 19,998 ops/sec [19,910..20,113] 🟢 +4.3% 19,857 ops/sec [19,454..19,933] → 18,948 ops/sec [18,715..19,053] 🔴 -4.6%
matchAll() with capture groups 9,958 ops/sec [9,859..10,018] → 10,263 ops/sec [9,830..10,511] ~ overlap (+3.1%) 12,394 ops/sec [12,112..12,770] → 11,761 ops/sec [11,678..11,777] 🔴 -5.1%
replace() with global regex 18,625 ops/sec [18,515..19,069] → 18,977 ops/sec [17,390..19,836] ~ overlap (+1.9%) 19,256 ops/sec [18,667..19,669] → 17,971 ops/sec [17,097..18,692] ~ overlap (-6.7%)
search() with regex 38,474 ops/sec [38,230..38,562] → 39,632 ops/sec [39,172..40,517] 🟢 +3.0% 38,260 ops/sec [37,573..38,659] → 36,106 ops/sec [35,779..37,127] 🔴 -5.6%
split() with regex separator 19,214 ops/sec [18,553..19,647] → 19,634 ops/sec [19,406..20,316] ~ overlap (+2.2%) 19,808 ops/sec [19,485..20,274] → 18,540 ops/sec [18,463..19,112] 🔴 -6.4%
strings.js — Interp: 🔴 14, 5 unch. · avg -4.3% · Bytecode: 🟢 6, 🔴 1, 12 unch. · avg +2.4%
Benchmark Interpreted Δ Bytecode Δ
string concatenation 152,108 ops/sec [147,886..154,477] → 152,740 ops/sec [149,384..153,961] ~ overlap (+0.4%) 110,158 ops/sec [109,855..110,669] → 113,353 ops/sec [109,054..115,419] ~ overlap (+2.9%)
template literal 307,031 ops/sec [298,502..311,138] → 294,786 ops/sec [292,631..307,837] ~ overlap (-4.0%) 194,494 ops/sec [192,934..197,770] → 185,964 ops/sec [185,131..186,348] 🔴 -4.4%
string repeat 180,007 ops/sec [172,973..181,708] → 173,334 ops/sec [168,680..177,509] ~ overlap (-3.7%) 206,594 ops/sec [203,507..207,714] → 210,324 ops/sec [208,883..211,457] 🟢 +1.8%
split and join 63,982 ops/sec [63,481..64,723] → 62,061 ops/sec [60,979..63,030] 🔴 -3.0% 68,801 ops/sec [67,507..69,264] → 68,839 ops/sec [68,108..70,570] ~ overlap (+0.1%)
indexOf and includes 78,882 ops/sec [76,141..83,438] → 73,914 ops/sec [72,912..76,289] ~ overlap (-6.3%) 80,981 ops/sec [80,142..81,176] → 81,081 ops/sec [79,426..83,017] ~ overlap (+0.1%)
toUpperCase and toLowerCase 92,330 ops/sec [89,114..93,189] → 85,951 ops/sec [82,866..88,438] 🔴 -6.9% 107,564 ops/sec [106,733..108,622] → 112,794 ops/sec [111,657..116,256] 🟢 +4.9%
slice and substring 71,981 ops/sec [71,836..72,377] → 68,430 ops/sec [67,885..69,398] 🔴 -4.9% 85,251 ops/sec [84,684..86,410] → 86,087 ops/sec [84,894..86,427] ~ overlap (+1.0%)
trim operations 80,897 ops/sec [79,536..82,439] → 76,560 ops/sec [75,746..77,338] 🔴 -5.4% 100,851 ops/sec [99,876..101,328] → 101,426 ops/sec [96,979..102,243] ~ overlap (+0.6%)
replace and replaceAll 83,125 ops/sec [82,853..83,841] → 81,715 ops/sec [80,670..82,706] 🔴 -1.7% 86,674 ops/sec [86,070..86,828] → 86,740 ops/sec [83,264..91,026] ~ overlap (+0.1%)
startsWith and endsWith 63,376 ops/sec [62,754..64,867] → 59,514 ops/sec [59,248..59,980] 🔴 -6.1% 65,055 ops/sec [63,421..66,752] → 68,701 ops/sec [67,905..70,152] 🟢 +5.6%
padStart and padEnd 92,116 ops/sec [89,817..92,488] → 89,008 ops/sec [87,344..90,221] ~ overlap (-3.4%) 99,213 ops/sec [99,041..99,677] → 101,595 ops/sec [93,033..103,890] ~ overlap (+2.4%)
identity tag, no substitutions 186,577 ops/sec [185,689..187,414] → 175,585 ops/sec [171,570..176,709] 🔴 -5.9% 550,543 ops/sec [543,964..560,556] → 579,169 ops/sec [559,811..591,704] ~ overlap (+5.2%)
tag with 1 substitution 37,282 ops/sec [37,015..37,594] → 36,192 ops/sec [35,619..36,630] 🔴 -2.9% 49,235 ops/sec [48,962..49,302] → 52,353 ops/sec [52,303..52,750] 🟢 +6.3%
tag with 3 substitutions 20,252 ops/sec [19,683..20,781] → 19,414 ops/sec [19,022..19,596] 🔴 -4.1% 28,518 ops/sec [27,649..29,463] → 29,300 ops/sec [28,981..29,448] ~ overlap (+2.7%)
tag with 6 substitutions 11,946 ops/sec [11,935..11,953] → 11,370 ops/sec [11,240..11,647] 🔴 -4.8% 16,285 ops/sec [15,864..16,636] → 17,573 ops/sec [17,214..17,784] 🟢 +7.9%
String.raw, no substitutions 253,058 ops/sec [245,469..255,115] → 242,691 ops/sec [242,086..243,443] 🔴 -4.1% 245,221 ops/sec [238,061..250,797] → 240,215 ops/sec [234,992..243,899] ~ overlap (-2.0%)
String.raw, 2 substitutions 178,558 ops/sec [175,412..192,659] → 170,379 ops/sec [166,892..173,685] 🔴 -4.6% 172,970 ops/sec [170,074..177,944] → 175,999 ops/sec [174,494..176,567] ~ overlap (+1.8%)
tag accessing .raw array 72,003 ops/sec [70,556..72,385] → 70,052 ops/sec [68,772..70,303] 🔴 -2.7% 90,960 ops/sec [90,280..93,053] → 94,878 ops/sec [92,715..95,649] ~ overlap (+4.3%)
method as tag (this binding) 27,785 ops/sec [26,895..28,322] → 25,472 ops/sec [25,358..26,222] 🔴 -8.3% 39,125 ops/sec [38,539..39,785] → 40,826 ops/sec [40,229..41,575] 🟢 +4.3%
tsv.js — Interp: 🟢 5, 4 unch. · avg +5.5% · Bytecode: 🟢 2, 🔴 2, 5 unch. · avg -0.5%
Benchmark Interpreted Δ Bytecode Δ
parse simple 3-column TSV 45,450 ops/sec [45,143..46,038] → 48,746 ops/sec [47,077..51,479] 🟢 +7.3% 50,839 ops/sec [49,083..52,766] → 51,638 ops/sec [50,797..52,310] ~ overlap (+1.6%)
parse 10-row TSV 12,585 ops/sec [12,374..12,647] → 13,219 ops/sec [12,631..13,558] ~ overlap (+5.0%) 13,496 ops/sec [13,151..14,294] → 13,425 ops/sec [13,207..13,856] ~ overlap (-0.5%)
parse 100-row TSV 2,008 ops/sec [1,992..2,058] → 2,107 ops/sec [2,052..2,119] ~ overlap (+4.9%) 2,073 ops/sec [2,046..2,129] → 2,133 ops/sec [2,079..2,192] ~ overlap (+2.9%)
parse TSV with backslash-escaped fields 9,198 ops/sec [9,113..9,406] → 9,398 ops/sec [9,238..9,458] ~ overlap (+2.2%) 9,723 ops/sec [9,509..9,952] → 10,104 ops/sec [10,027..10,140] 🟢 +3.9%
parse without headers (array of arrays) 5,399 ops/sec [5,308..5,471] → 5,912 ops/sec [5,700..6,067] 🟢 +9.5% 5,793 ops/sec [5,620..5,827] → 6,039 ops/sec [5,962..6,061] 🟢 +4.2%
stringify array of objects 38,770 ops/sec [38,202..39,277] → 40,564 ops/sec [39,767..41,252] 🟢 +4.6% 43,432 ops/sec [42,200..43,654] → 40,149 ops/sec [39,919..40,426] 🔴 -7.6%
stringify array of arrays 10,637 ops/sec [10,479..10,840] → 11,690 ops/sec [11,320..12,930] 🟢 +9.9% 11,783 ops/sec [11,707..11,960] → 10,666 ops/sec [10,517..10,759] 🔴 -9.5%
stringify with values needing escaping 31,001 ops/sec [30,612..32,286] → 30,702 ops/sec [30,301..32,809] ~ overlap (-1.0%) 31,657 ops/sec [31,466..31,840] → 31,761 ops/sec [31,583..31,880] ~ overlap (+0.3%)
parse then stringify 6,739 ops/sec [6,707..6,857] → 7,205 ops/sec [7,048..7,536] 🟢 +6.9% 7,317 ops/sec [7,280..7,355] → 7,330 ops/sec [7,308..7,373] ~ overlap (+0.2%)
typed-arrays.js — Interp: 🔴 20, 2 unch. · avg -23.2% · Bytecode: 🟢 4, 🔴 10, 8 unch. · avg -6.9%
Benchmark Interpreted Δ Bytecode Δ
new Int32Array(0) 149,918 ops/sec [143,248..150,527] → 137,950 ops/sec [136,808..140,255] 🔴 -8.0% 160,971 ops/sec [157,499..166,000] → 163,256 ops/sec [161,741..165,992] ~ overlap (+1.4%)
new Int32Array(100) 137,430 ops/sec [133,153..139,700] → 130,287 ops/sec [127,748..132,167] 🔴 -5.2% 151,635 ops/sec [146,895..152,015] → 149,116 ops/sec [146,754..149,906] ~ overlap (-1.7%)
new Int32Array(1000) 104,924 ops/sec [102,327..105,672] → 92,578 ops/sec [88,150..94,626] 🔴 -11.8% 105,941 ops/sec [103,540..110,413] → 111,164 ops/sec [106,394..113,243] ~ overlap (+4.9%)
new Float64Array(100) 130,586 ops/sec [128,893..131,568] → 124,488 ops/sec [122,729..126,694] 🔴 -4.7% 145,491 ops/sec [141,504..147,969] → 143,774 ops/sec [142,866..146,502] ~ overlap (-1.2%)
Int32Array.from([...]) 92,591 ops/sec [91,579..93,556] → 88,047 ops/sec [87,069..88,535] 🔴 -4.9% 99,719 ops/sec [97,294..100,398] → 98,177 ops/sec [96,402..99,486] ~ overlap (-1.5%)
Int32Array.of(1, 2, 3, 4, 5) 149,145 ops/sec [148,160..150,894] → 135,636 ops/sec [131,378..139,971] 🔴 -9.1% 161,409 ops/sec [160,159..163,042] → 157,786 ops/sec [156,083..159,168] 🔴 -2.2%
sequential write 100 elements 1,743 ops/sec [1,708..1,773] → 1,626 ops/sec [1,596..1,682] 🔴 -6.7% 5,394 ops/sec [5,256..5,530] → 5,651 ops/sec [5,603..5,714] 🟢 +4.8%
sequential read 100 elements 1,800 ops/sec [1,723..1,821] → 1,627 ops/sec [1,616..1,642] 🔴 -9.6% 9,141 ops/sec [5,308..9,216] → 5,251 ops/sec [5,212..5,482] ~ overlap (-42.6%)
Float64Array write 100 elements 1,689 ops/sec [1,655..1,705] → 1,496 ops/sec [1,471..1,508] 🔴 -11.4% 6,412 ops/sec [6,343..6,450] → 3,982 ops/sec [3,968..4,032] 🔴 -37.9%
fill(42) 27,304 ops/sec [27,055..27,343] → 25,179 ops/sec [25,076..25,318] 🔴 -7.8% 45,812 ops/sec [45,701..46,013] → 27,671 ops/sec [27,333..32,863] 🔴 -39.6%
slice() 108,575 ops/sec [107,857..109,948] → 109,680 ops/sec [109,619..109,920] ~ overlap (+1.0%) 191,528 ops/sec [190,436..193,107] → 124,568 ops/sec [123,536..124,975] 🔴 -35.0%
map(x => x * 2) 5,155 ops/sec [3,013..5,188] → 2,810 ops/sec [2,788..2,832] 🔴 -45.5% 7,052 ops/sec [7,017..7,078] → 4,207 ops/sec [4,096..4,290] 🔴 -40.3%
filter(x => x > 50) 5,515 ops/sec [5,492..5,603] → 2,954 ops/sec [2,922..3,056] 🔴 -46.4% 7,757 ops/sec [7,699..7,809] → 4,489 ops/sec [4,391..4,532] 🔴 -42.1%
reduce (sum) 5,187 ops/sec [5,148..5,208] → 2,794 ops/sec [2,746..2,816] 🔴 -46.1% 6,651 ops/sec [6,635..6,681] → 3,779 ops/sec [3,710..3,821] 🔴 -43.2%
sort() 169,769 ops/sec [92,439..170,942] → 100,175 ops/sec [96,537..103,733] ~ overlap (-41.0%) 164,606 ops/sec [164,285..165,812] → 102,386 ops/sec [101,374..103,239] 🔴 -37.8%
indexOf() 350,908 ops/sec [346,757..352,984] → 202,104 ops/sec [200,132..203,407] 🔴 -42.4% 402,553 ops/sec [401,906..402,890] → 249,769 ops/sec [248,509..252,757] 🔴 -38.0%
reverse() 283,691 ops/sec [281,106..287,222] → 157,777 ops/sec [156,850..159,244] 🔴 -44.4% 323,995 ops/sec [323,356..324,824] → 188,172 ops/sec [186,768..191,186] 🔴 -41.9%
create view over existing buffer 281,755 ops/sec [280,560..284,670] → 157,734 ops/sec [157,007..160,379] 🔴 -44.0% 295,526 ops/sec [293,201..296,239] → 333,770 ops/sec [193,750..335,968] ~ overlap (+12.9%)
subarray() 331,136 ops/sec [328,099..337,128] → 183,181 ops/sec [180,714..186,299] 🔴 -44.7% 244,664 ops/sec [242,888..383,394] → 415,249 ops/sec [411,219..418,377] 🟢 +69.7%
set() from array 407,557 ops/sec [405,794..412,332] → 217,962 ops/sec [217,702..221,230] 🔴 -46.5% 293,403 ops/sec [290,304..294,089] → 543,850 ops/sec [541,320..544,418] 🟢 +85.4%
for-of loop 4,568 ops/sec [4,541..4,597] → 3,913 ops/sec [2,419..3,996] 🔴 -14.3% 8,455 ops/sec [8,443..8,495] → 14,465 ops/sec [14,278..14,639] 🟢 +71.1%
spread into array 16,859 ops/sec [16,822..16,952] → 14,188 ops/sec [14,060..14,414] 🔴 -15.8% 61,050 ops/sec [38,493..62,741] → 62,935 ops/sec [62,659..63,986] ~ overlap (+3.1%)
uint8array-encoding.js — Interp: 🟢 14, 🔴 2, 2 unch. · avg +40.7% · Bytecode: 🟢 9, 🔴 2, 7 unch. · avg +1.7%
Benchmark Interpreted Δ Bytecode Δ
short (5 bytes) 298,881 ops/sec [283,010..308,833] → 294,758 ops/sec [290,915..300,954] ~ overlap (-1.4%) 482,632 ops/sec [469,005..485,675] → 497,320 ops/sec [485,685..506,445] 🟢 +3.0%
medium (450 bytes) 162,123 ops/sec [159,636..164,710] → 152,065 ops/sec [149,469..155,610] 🔴 -6.2% 205,677 ops/sec [201,623..206,480] → 199,393 ops/sec [197,939..203,203] ~ overlap (-3.1%)
large (4096 bytes) 33,308 ops/sec [32,364..34,200] → 31,558 ops/sec [31,207..31,655] 🔴 -5.3% 35,161 ops/sec [34,187..35,864] → 34,138 ops/sec [32,746..34,617] ~ overlap (-2.9%)
base64url alphabet 114,341 ops/sec [113,606..115,005] → 106,847 ops/sec [104,091..160,715] ~ overlap (-6.6%) 126,458 ops/sec [124,111..127,880] → 122,667 ops/sec [121,513..123,409] 🔴 -3.0%
omitPadding 176,417 ops/sec [173,547..178,680] → 268,051 ops/sec [266,236..271,151] 🟢 +51.9% 206,232 ops/sec [203,780..210,827] → 219,170 ops/sec [216,827..226,841] 🟢 +6.3%
short (8 chars) 160,473 ops/sec [158,906..162,435] → 233,724 ops/sec [233,196..234,035] 🟢 +45.6% 169,554 ops/sec [168,453..170,250] → 185,112 ops/sec [184,667..186,378] 🟢 +9.2%
medium (600 chars) 73,539 ops/sec [72,697..74,294] → 118,640 ops/sec [118,032..119,701] 🟢 +61.3% 77,248 ops/sec [77,106..78,042] → 76,684 ops/sec [76,480..77,323] ~ overlap (-0.7%)
large (5464 chars) 13,939 ops/sec [13,707..14,116] → 23,806 ops/sec [23,644..24,058] 🟢 +70.8% 14,257 ops/sec [14,174..14,630] → 13,763 ops/sec [13,464..14,187] ~ overlap (-3.5%)
short (5 bytes) 303,667 ops/sec [298,825..306,335] → 497,861 ops/sec [493,674..500,000] 🟢 +63.9% 488,462 ops/sec [482,542..494,502] → 486,263 ops/sec [482,703..495,593] ~ overlap (-0.5%)
medium (450 bytes) 142,443 ops/sec [140,033..143,971] → 217,043 ops/sec [215,945..217,502] 🟢 +52.4% 159,921 ops/sec [158,156..161,625] → 169,891 ops/sec [166,283..182,873] 🟢 +6.2%
large (4096 bytes) 26,261 ops/sec [24,940..26,988] → 40,970 ops/sec [40,453..41,118] 🟢 +56.0% 23,673 ops/sec [23,362..25,125] → 27,457 ops/sec [26,958..28,960] 🟢 +16.0%
short (10 chars) 179,701 ops/sec [179,131..181,628] → 259,239 ops/sec [257,895..262,775] 🟢 +44.3% 187,036 ops/sec [185,693..188,631] → 199,861 ops/sec [198,882..203,696] 🟢 +6.9%
medium (900 chars) 121,686 ops/sec [121,081..122,540] → 178,497 ops/sec [177,577..179,807] 🟢 +46.7% 115,481 ops/sec [114,716..116,036] → 126,974 ops/sec [125,171..134,360] 🟢 +10.0%
large (8192 chars) 32,279 ops/sec [32,086..33,876] → 49,638 ops/sec [48,446..50,058] 🟢 +53.8% 28,705 ops/sec [27,399..28,942] → 34,103 ops/sec [33,035..34,347] 🟢 +18.8%
setFromBase64 (450 bytes) 73,087 ops/sec [72,921..73,290] → 115,816 ops/sec [114,797..116,209] 🟢 +58.5% 78,652 ops/sec [78,398..80,134] → 81,939 ops/sec [80,797..82,782] 🟢 +4.2%
setFromHex (450 bytes) 104,084 ops/sec [101,621..104,464] → 165,496 ops/sec [163,986..166,319] 🟢 +59.0% 120,287 ops/sec [119,326..121,891] → 121,187 ops/sec [121,039..121,333] ~ overlap (+0.7%)
toBase64 → fromBase64 (450 bytes) 57,290 ops/sec [56,358..57,636] → 84,569 ops/sec [83,706..85,346] 🟢 +47.6% 60,320 ops/sec [59,601..60,462] → 59,689 ops/sec [59,441..59,931] ~ overlap (-1.0%)
toHex → fromHex (450 bytes) 78,312 ops/sec [75,161..79,196] → 109,527 ops/sec [108,300..110,562] 🟢 +39.9% 119,159 ops/sec [118,426..120,240] → 76,063 ops/sec [74,281..78,562] 🔴 -36.2%
weak-collections.js — Interp: 🔴 12, 3 unch. · avg -32.0% · Bytecode: 🟢 12, 3 unch. · avg +51.9%
Benchmark Interpreted Δ Bytecode Δ
constructor from 50 entries 22,220 ops/sec [21,579..22,253] → 12,560 ops/sec [12,481..13,840] 🔴 -43.5% 12,456 ops/sec [12,186..12,668] → 11,863 ops/sec [11,818..12,919] ~ overlap (-4.8%)
set 50 object keys 8,038 ops/sec [8,011..8,051] → 4,678 ops/sec [4,589..4,746] 🔴 -41.8% 10,939 ops/sec [6,392..11,031] → 6,310 ops/sec [6,172..6,836] ~ overlap (-42.3%)
get lookups (50 entries) 105,244 ops/sec [104,504..105,874] → 62,672 ops/sec [61,920..63,168] 🔴 -40.5% 98,136 ops/sec [96,869..99,157] → 180,452 ops/sec [98,251..182,018] ~ overlap (+83.9%)
has checks (50 entries) 133,621 ops/sec [132,857..134,137] → 84,681 ops/sec [83,783..85,702] 🔴 -36.6% 127,283 ops/sec [123,773..127,846] → 230,851 ops/sec [229,387..231,080] 🟢 +81.4%
delete entries 4,522 ops/sec [4,453..4,532] → 4,486 ops/sec [4,440..4,650] ~ overlap (-0.8%) 6,238 ops/sec [6,146..6,327] → 10,864 ops/sec [10,799..10,959] 🟢 +74.2%
non-registered symbol keys 10,782 ops/sec [10,741..10,847] → 10,880 ops/sec [10,740..11,029] ~ overlap (+0.9%) 15,292 ops/sec [15,261..15,299] → 26,379 ops/sec [26,220..26,585] 🟢 +72.5%
getOrInsert 4,437 ops/sec [4,394..4,473] → 4,463 ops/sec [4,435..4,485] ~ overlap (+0.6%) 6,440 ops/sec [6,420..6,651] → 11,325 ops/sec [11,275..11,412] 🟢 +75.9%
getOrInsertComputed 3,572 ops/sec [3,496..3,589] → 2,215 ops/sec [2,202..2,223] 🔴 -38.0% 3,060 ops/sec [3,036..3,137] → 5,367 ops/sec [5,339..5,374] 🟢 +75.4%
forced gc live-key retention 7,268 ops/sec [7,261..7,296] → 4,684 ops/sec [4,526..4,713] 🔴 -35.6% 5,499 ops/sec [5,425..5,581] → 9,695 ops/sec [9,597..9,781] 🟢 +76.3%
constructor from 50 values 29,391 ops/sec [29,194..29,441] → 16,798 ops/sec [16,147..17,090] 🔴 -42.8% 16,614 ops/sec [16,316..16,841] → 31,068 ops/sec [30,908..31,385] 🟢 +87.0%
add 50 object values 8,589 ops/sec [8,540..8,635] → 5,158 ops/sec [5,102..5,213] 🔴 -39.9% 7,037 ops/sec [6,997..7,053] → 12,762 ops/sec [12,718..12,866] 🟢 +81.4%
has checks (50 values) 135,554 ops/sec [134,837..136,251] → 80,594 ops/sec [79,884..82,542] 🔴 -40.5% 129,048 ops/sec [127,585..211,097] → 230,115 ops/sec [227,662..231,200] 🟢 +78.3%
delete values 22,772 ops/sec [22,707..22,891] → 13,092 ops/sec [12,847..13,384] 🔴 -42.5% 23,838 ops/sec [23,324..24,031] → 27,451 ops/sec [27,348..27,557] 🟢 +15.2%
non-registered symbol values 19,429 ops/sec [19,289..19,570] → 11,356 ops/sec [11,242..11,472] 🔴 -41.6% 26,137 ops/sec [26,055..26,281] → 29,396 ops/sec [29,333..29,508] 🟢 +12.5%
forced gc pruning smoke 8,966 ops/sec [8,924..9,043] → 5,626 ops/sec [5,597..5,701] 🔴 -37.3% 11,100 ops/sec [10,944..11,210] → 12,416 ops/sec [12,253..12,487] 🟢 +11.9%

Measured on ubuntu-latest x64. Benchmark ranges compare cached main-branch min/max ops/sec with the PR run; overlapping ranges are treated as unchanged noise. Percentage deltas are secondary context.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 29, 2026

Suite Timing

Suite Metric Interpreted Bytecode
Tests Total 8243 8243
Tests Passed 8202 ✅ 8243 ✅
Tests Skipped 41 0
Tests Workers 4 4
Tests Test Duration 1.51s 1.90s
Tests Lex (cumulative) 155.3ms 137.9ms
Tests Parse (cumulative) 241.2ms 326.6ms
Tests Compile (cumulative) 184.9ms
Tests Execute (cumulative) 1.52s 1.52s
Tests Engine Total (cumulative) 1.91s 2.16s
Tests Lex (avg/worker) 38.8ms 34.5ms
Tests Parse (avg/worker) 60.3ms 81.6ms
Tests Compile (avg/worker) 46.2ms
Tests Execute (avg/worker) 379.1ms 378.8ms
Tests Engine Total (avg/worker) 478.2ms 541.1ms
Benchmarks Total 407 407
Benchmarks Workers 4 4
Benchmarks Duration 2.49min 2.41min

Measured on ubuntu-latest x64.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
website/src/__tests__/markdown-negotiation.test.ts (1)

22-31: Add parser edge-case assertions for invalid/clamped q values.

Given parseQuality clamps and normalizes values, lock those behaviors in tests (q=1.5, q=-1, q=abc) to prevent regressions in negotiation semantics.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@website/src/__tests__/markdown-negotiation.test.ts` around lines 22 - 31, Add
tests around acceptsMarkdown that lock parseQuality's clamping/normalization:
assert that "text/markdown;q=1.5" is treated as q=1 and returns true, while
invalid or out-of-range values are treated as 0 and return false (e.g.,
"text/markdown;q=-1" -> false and "text/markdown;q=abc" -> false). Use the
existing acceptsMarkdown test harness and reference parseQuality behavior to
ensure these three edge cases are covered.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@website/src/lib/site-markdown.ts`:
- Around line 99-101: The code dereferences EXAMPLES items into heroExample (and
similar usage at the later block around lines 214-217), which will throw if
EXAMPLES is empty; update the selection logic to guard against an empty array by
first checking EXAMPLES.length > 0 and if empty using a safe default object
(e.g., { id: "", label: "", desc: "", code: "" }) so downstream reads of
desc/label/code won't crash; apply this same defensive pattern to both the
heroExample assignment and the other EXAMPLES lookups referenced in the file.

In `@website/src/proxy.ts`:
- Around line 16-17: The current pathname checks only handle subpaths but miss
the exact roots; update the conditional logic that uses the pathname variable in
proxy.ts (the block with "if (pathname.startsWith(...))") to also return true
when pathname is exactly "/api" or "/_next" (i.e., treat pathname === "/api" and
pathname === "/_next" as skips in addition to startsWith("/api/") and
startsWith("/_next/")). Ensure both exact-match and prefix-match cases are
covered so exact root paths are not rewritten.

---

Nitpick comments:
In `@website/src/__tests__/markdown-negotiation.test.ts`:
- Around line 22-31: Add tests around acceptsMarkdown that lock parseQuality's
clamping/normalization: assert that "text/markdown;q=1.5" is treated as q=1 and
returns true, while invalid or out-of-range values are treated as 0 and return
false (e.g., "text/markdown;q=-1" -> false and "text/markdown;q=abc" -> false).
Use the existing acceptsMarkdown test harness and reference parseQuality
behavior to ensure these three edge cases are covered.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: caad7118-71bb-42ae-9b89-b7425f34073b

📥 Commits

Reviewing files that changed from the base of the PR and between 2c96f54 and 06d8bdf.

📒 Files selected for processing (5)
  • website/src/__tests__/markdown-negotiation.test.ts
  • website/src/app/agent-markdown/[[...path]]/route.ts
  • website/src/lib/markdown-negotiation.ts
  • website/src/lib/site-markdown.ts
  • website/src/proxy.ts

Comment thread website/src/lib/site-markdown.ts Outdated
Comment thread website/src/proxy.ts Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
website/src/lib/site-markdown.ts (1)

28-32: Escape YAML frontmatter values before interpolation.

Raw scalar interpolation can break frontmatter parsing if title or description ever contains YAML-significant characters (for example : or newlines).

Proposed patch
+function yamlQuote(value: string): string {
+  return JSON.stringify(value);
+}
+
 function frontmatter(title: string, description: string): string {
-  return ["---", `title: ${title}`, `description: ${description}`, "---"].join(
+  return [
+    "---",
+    `title: ${yamlQuote(title)}`,
+    `description: ${yamlQuote(description)}`,
+    "---",
+  ].join(
     "\n",
   );
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@website/src/lib/site-markdown.ts` around lines 28 - 32, The frontmatter
function currently interpolates title and description raw, which can break YAML
if they contain colons, newlines, or quotes; update the frontmatter(title,
description) implementation to escape or properly quote both values before
joining (e.g., use a safe serializer like js-yaml's dump for scalars or
JSON.stringify to produce a quoted/escaped string) so the returned frontmatter
always yields valid YAML; ensure both title and description are passed through
the chosen escaping/serialization function before being inserted into the
`title:` and `description:` lines.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@website/src/lib/site-markdown.ts`:
- Around line 28-32: The frontmatter function currently interpolates title and
description raw, which can break YAML if they contain colons, newlines, or
quotes; update the frontmatter(title, description) implementation to escape or
properly quote both values before joining (e.g., use a safe serializer like
js-yaml's dump for scalars or JSON.stringify to produce a quoted/escaped string)
so the returned frontmatter always yields valid YAML; ensure both title and
description are passed through the chosen escaping/serialization function before
being inserted into the `title:` and `description:` lines.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d3e3dde6-fbb6-4a45-a26c-b42a22d3d4c3

📥 Commits

Reviewing files that changed from the base of the PR and between 06d8bdf and b30cfa3.

📒 Files selected for processing (3)
  • website/src/__tests__/markdown-negotiation.test.ts
  • website/src/lib/site-markdown.ts
  • website/src/proxy.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • website/src/proxy.ts
  • website/src/tests/markdown-negotiation.test.ts

@frostney frostney merged commit 92e1834 into main Apr 29, 2026
12 checks passed
@frostney frostney deleted the t3code/markdown-agent-responses branch April 29, 2026 11:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant