Skip to content

Replace browser_ppx with ppx_platform - #404

Merged
davesnx merged 10 commits into
mainfrom
ppx-platform-dep
Oct 21, 2026
Merged

davesnx merged 10 commits into
mainfrom
ppx-platform-dep

Conversation

@davesnx

@davesnx davesnx commented Oct 15, 2026 •

Copy link
Copy Markdown
Member

browser_ppx is replaced by its own package, ppx_platform, and this repo moves to its 0.3.0 syntax. server-reason-react.browser_ppx is removed.

  • Breaking: replace server-reason-react.browser_ppx with ppx_platform in dune pps. Flags stay the same, for example (pps ppx_platform -js server-reason-react.ppx -melange) for Melange.

  • Breaking: ppx_platform 0.3.0 renames the syntax. The old names give a compile error that names the replacement, for example [@platform js] was removed in 0.3.0, use [@melange_only].

    Removed Use
    let%browser_only, [%browser_only ...] let%melange_only, [%melange_only ...]
    [@browser_only], [@platform js] [@melange_only]
    [@platform native] [@native_only]
    Server / Client in switch%platform Native / Melange
    [@alert "-browser_only"] [@alert "-melange_only"]
  • Breaking: effect bodies are no longer wrapped automatically. Effects never run on the server (native React.useEffect* is a no-op), so this only matters at compile time: an effect body that uses Melange-only modules must be wrapped explicitly, React.useEffect0([%melange_only () => ...]). server-reason-react.ppx does not touch effects and does not depend on ppx_platform.

  • Breaking: Runtime.platform (Server | Client) is removed. ppx_platform matches case names, not the scrutinee, and nothing used the type.

  • melange.ppx lets externals through when they carry [@melange_only] (was [@platform js] / [@browser_only]), and its error hints use the new names.

  • Generated native code calls Ppx_platform.fail_melange_only. Runtime.Impossible_in_ssr and Runtime.fail_impossible_action_in_ssr are aliases of Ppx_platform.Melange_only and Ppx_platform.fail_melange_only, so existing with Runtime.Impossible_in_ssr _ handlers still catch it.

  • Requires ppx_platform >= 0.3.0 from opam-repository. There is no pin-depends and no ppx_platform pin in make pin.

  • The browser_ppx docs page is removed. The general syntax lives in the ppx_platform README. The parts specific to server-reason-react (dune setup with -melange, the Runtime.Impossible_in_ssr alias) are in documentation/get-started.mld. The guides list in index.mld keeps "Exclude client code from the native build", linked to that section.

Tests

At 37f7c1f, OCaml 5.4.0, against ppx_platform 0.3.0 installed from opam-repository (not pinned):

  • dune build, dune build @runtest --force, dune build @fmt: exit 0. The demo and router browser tests ran with node_modules from an existing checkout.
  • opam lint server-reason-react.opam: passed.
  • git grep for browser_only, [@platform js|native], Runtime.Server|Client|platform and Server => / Client => finds nothing outside CHANGES.md.
  • dune describe pp on demo/universal/native/shared/RR.re drops the [@melange_only] item and keeps the [@native_only] one. On ServerActionWithFormData.re, switch%platform keeps the Native branch.
  • packages/server-reason-react-ppx/cram/effect.t: server-reason-react.ppx leaves React.useEffect* calls as written; with ppx_platform in the same driver, an explicit [%melange_only ...] effect body becomes Ppx_platform.fail_melange_only.
  • packages/server-reason-react-ppx/cram/runtime_alias.t: a let%melange_only function called on native is caught by with Runtime.Impossible_in_ssr _. With Runtime declaring its own exception instead of the alias, the test fails (mutation check run at 149abc4).
  • A scratch file with [@@platform js] under (pps ppx_platform) fails with [ppx_platform] [@platform js] was removed in 0.3.0, use [@melange_only].

Risk: two-way door for this repo. Reverting restores browser_ppx and the old names. Downstream projects that already migrated to ppx_platform 0.3.0 names would need to switch back.

@vercel

vercel Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

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

Project Deployment Actions Updated
server-reason-react Ready Ready Preview Oct 20, 2026 3:55pm UTC

Request Review

@github-actions

github-actions Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Benchmarks

Comparison against main (0b1e0bb). Higher is better.

Benchmark main (ops/sec) PR (ops/sec) Change
trivial/renderToStaticMarkup 2,579,364 4,084,831 +58.4% 🟢
trivial/renderToString 2,197,236 2,617,840 +19.1% 🟢
depth/10 63,829 98,001 +53.5% 🟢
depth/25 25,103 39,079 +55.7% 🟢
depth/50 12,778 20,193 +58.0% 🟢
depth/100 6,422 9,872 +53.7% 🟢
width/10 38,656 60,694 +57.0% 🟢
width/100 3,958 6,394 +61.6% 🟢
width/500 726.85 1,184 +62.8% 🟢
width/1000 366.45 605.7 +65.3% 🟢
table/10 25,715 40,583 +57.8% 🟢
table/50 5,494 8,792 +60.0% 🟢
table/100 2,365 3,845 +62.6% 🟢
table/500 509.53 815.29 +60.0% 🟢
props/small 9,923 17,030 +71.6% 🟢
props/medium 3,465 5,931 +71.1% 🟢
props/large 1,181 2,199 +86.2% 🟢
realworld/ecommerce24 6,454 10,471 +62.2% 🟢
realworld/ecommerce48 3,444 5,564 +61.6% 🟢
realworld/dashboard 26,383 44,492 +68.6% 🟢
realworld/blog50 4,145 6,617 +59.7% 🟢
realworld/form 13,699 23,267 +69.8% 🟢
primitive/React.string 17,697,485 32,564,472 +84.0% 🟢
primitive/React.int 8,741,776 17,182,728 +96.6% 🟢
primitive/React.null 28,906,299 50,963,597 +76.3% 🟢
primitive/createElement_empty 10,857,634 21,323,355 +96.4% 🟢
primitive/createElement_children 935,560 1,702,441 +82.0% 🟢
primitive/React.array_10 909,098 1,700,371 +87.0% 🟢
primitive/React.array_100 102,692 193,524 +88.5% 🟢
primitive/React.list_10 930,413 1,705,556 +83.3% 🟢
primitive/React.list_100 103,599 190,967 +84.3% 🟢
rsc/trivial 311,427 512,563 +64.6% 🟢
rsc/depth/50 4,804 8,112 +68.9% 🟢
rsc/width/100 509.16 850.25 +67.0% 🟢
rsc/width/500 91.42 155.66 +70.3% 🟢
rsc/width/1000 41.2 70 +69.9% 🟢
rsc/table/100 257.55 437.15 +69.7% 🟢
rsc/table/500 45.85 79.39 +73.2% 🟢
streaming/renderToStream/wide100 3,576 4,153 +16.2% 🟢
streaming/renderToStream/suspense-drained 35,986 63,160 +75.5% 🟢
rsc/render_html/wide100 508.73 853.47 +67.8% 🟢
rsc/render_html/suspense 15,449 28,290 +83.1% 🟢
rsc/render_model/wide100 1,077 1,683 +56.3% 🟢
router/match/static-small-first 20,276,623 35,620,942 +75.7% 🟢
router/match/static-small-last 30,485,465 51,377,848 +68.5% 🟢
router/match/static-large-first 31,340,073 54,355,924 +73.4% 🟢
router/match/static-large-last 30,771,709 54,598,849 +77.4% 🟢
router/match/static-large-miss 2,802,079 4,432,011 +58.2% 🟢
router/match/dynamic-large-first 1,976,813 3,106,930 +57.2% 🟢
router/match/dynamic-large-last 2,121,451 3,445,045 +62.4% 🟢
router/endpoint/static-large-last 17,291,066 29,485,033 +70.5% 🟢
router/endpoint/dynamic-large-last 2,014,781 3,215,778 +59.6% 🟢
router/parse/path-plain 2,124,415 3,341,616 +57.3% 🟢
router/parse/path-encoded 1,413,520 2,601,347 +84.0% 🟢
router/parse/search 2,342,107 4,310,028 +84.0% 🟢

Changes within ±5% are likely noise from the CI runner.

@davesnx davesnx changed the title Build browser_ppx on top of ppx_platform Replace browser_ppx with ppx_platform Oct 15, 2026
@davesnx
davesnx marked this pull request as ready for review October 16, 2026 14:38
* origin/main:
  Use gh-ci-action v1.0.0 in CI (#407)
  Update ocaml/setup-ocaml to v3.9.0 (#406)
  Fix router redirects, search encoding and boundaries; add metadata tags and a server adapter (#403)
  Ignore .agents
  Delete more md plans
  Remove plan
@davesnx
davesnx merged commit 056a6ac into main Oct 21, 2026
6 checks passed
@davesnx
davesnx deleted the ppx-platform-dep branch October 21, 2026 14:42

This branch was successfully deployed

1 active deployment
Preview — 8ebca0b4 Deployed Oct 20, 2026 by vercel[bot]
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