diff --git a/apps/docs/__tests__/LandingPageInstallInstructions_.test.res b/apps/docs/__tests__/LandingPageInstallInstructions_.test.res
new file mode 100644
index 000000000..586db9134
--- /dev/null
+++ b/apps/docs/__tests__/LandingPageInstallInstructions_.test.res
@@ -0,0 +1,24 @@
+open Vitest
+
+test("install instructions update their class prop and keep copying available", async () => {
+ let screen = await render( )
+ let root = switch document->WebAPI.Document.querySelector(".initial-layout") {
+ | Value(root) => root
+ | Null => failwith("expected the install instructions root")
+ }
+ await element(root)->toHaveAttribute("class", "w-full max-w-400 initial-layout")
+
+ await screen->rerender( )
+
+ await element(root)->toHaveAttribute("class", "w-full max-w-400 updated-layout")
+ let template = await screen->getByLabelText("Copy npx create-rescript-app command")
+ await element(template)->toBeVisible
+
+ await screen->rerender( )
+
+ await element(root)->toHaveAttribute("class", "w-full max-w-400 ")
+ let copy = await screen->getByLabelText("Copy npm install rescript command")
+ await copy->click
+ let feedback = await screen->getByText("Copied!")
+ await element(feedback)->toBeVisible
+})
diff --git a/apps/docs/package.json b/apps/docs/package.json
index 7ed76418c..9607334f8 100644
--- a/apps/docs/package.json
+++ b/apps/docs/package.json
@@ -16,7 +16,7 @@
"check:algolia-public-env": "node _scripts/LogAlgoliaEnvStatus.mjs",
"build": "yarn build:res && yarn build:scripts && yarn check:algolia-public-env && yarn build:update-index && yarn build:vite && yarn build:generate-sitemap",
"ci:format": "cd ../.. && oxfmt --check",
- "ci:homepage-performance": "node scripts/homepage-performance.mjs",
+ "ci:homepage-performance": "node --test scripts/__tests__/homepage-compiler.test.mjs && node scripts/homepage-performance.mjs",
"ci:test": "vitest --run --browser.headless",
"ci:test:e2e": "cypress run --config-file cypress.homepage.config.mjs --browser chrome",
"ci:test:scripts": "vitest run --config vitest.scripts.config.mjs",
@@ -78,14 +78,17 @@
"vfile-matter": "^5.0.1"
},
"devDependencies": {
+ "@babel/core": "^7.29.7",
"@react-router/dev": "^8.3.1",
"@responsive-image/core": "2.1.0",
"@responsive-image/vite-plugin": "3.0.1",
+ "@rolldown/plugin-babel": "^0.2.4",
"@tailwindcss/vite": "^4.3.0",
"@types/react": "^19.2.14",
"@vitejs/plugin-react": "^6.0.1",
"@vitest/browser-playwright": "^5.0.0",
"auto-image-converter": "^2.2.0",
+ "babel-plugin-react-compiler": "^1.0.0",
"chokidar": "^4.0.3",
"cypress": "^15.13.1",
"cypress-real-events": "^1.15.1",
@@ -96,6 +99,7 @@
"oxfmt": "^0.46.0",
"playwright": "^1.63.0",
"remark-cli": "^12.0.1",
+ "rolldown": "1.2.8",
"search-insights": "^2.17.3",
"tailwindcss": "^4",
"to-vfile": "^8.0.0",
diff --git a/apps/docs/scripts/__tests__/homepage-compiler.test.mjs b/apps/docs/scripts/__tests__/homepage-compiler.test.mjs
new file mode 100644
index 000000000..20c19a1ba
--- /dev/null
+++ b/apps/docs/scripts/__tests__/homepage-compiler.test.mjs
@@ -0,0 +1,258 @@
+import assert from "node:assert/strict";
+import { readFile, readdir } from "node:fs/promises";
+import test from "node:test";
+import { fileURLToPath } from "node:url";
+import { parseSync, transformAsync, traverse, types } from "@babel/core";
+import { homepageCompilerOptions } from "../../vite-react-compiler.mjs";
+
+const optedInComponents = [
+ {
+ name: "LandingPageIntro",
+ directory: "src/components",
+ compiledNames: ["LandingPageIntro"],
+ },
+ {
+ name: "LandingPageInstallInstructions",
+ directory: "src/components",
+ compiledNames: ["LandingPageInstallInstructions"],
+ },
+ {
+ name: "LandingPageTrustedBy",
+ directory: "src/components",
+ compiledNames: ["LandingPageTrustedBy"],
+ },
+ {
+ name: "NavbarPrimary",
+ directory: "src/components",
+ compiledNames: [
+ "NavbarPrimary",
+ "NavbarPrimary$LeftContent",
+ "NavbarPrimary$RightContent",
+ ],
+ },
+];
+const optedInNames = optedInComponents.flatMap(
+ ({ compiledNames }) => compiledNames,
+);
+
+async function transformComponent({ name, directory }) {
+ const filename = fileURLToPath(
+ new URL(`../../${directory}/${name}.jsx`, import.meta.url),
+ );
+ const result = await transformAsync(await readFile(filename, "utf8"), {
+ filename,
+ ast: true,
+ code: false,
+ babelrc: false,
+ configFile: false,
+ parserOpts: { plugins: ["jsx"] },
+ presets: homepageCompilerOptions().presets.map((preset) => preset.preset),
+ });
+ assert.ok(result?.ast, `${name} must produce a Babel AST`);
+ return result.ast;
+}
+
+function cacheBindings(ast) {
+ return ast.program.body.flatMap((node) => {
+ if (
+ !types.isImportDeclaration(node) ||
+ node.source.value !== "react/compiler-runtime"
+ ) {
+ return [];
+ }
+ return node.specifiers.flatMap((specifier) =>
+ types.isImportSpecifier(specifier) &&
+ types.isIdentifier(specifier.imported, { name: "c" })
+ ? [specifier.local.name]
+ : [],
+ );
+ });
+}
+
+function cachedComponentNames(ast) {
+ const bindings = cacheBindings(ast);
+ const names = new Set();
+ traverse(ast, {
+ CallExpression(path) {
+ if (
+ types.isIdentifier(path.node.callee) &&
+ bindings.includes(path.node.callee.name)
+ ) {
+ const component = path.getFunctionParent();
+ assert.ok(component?.isFunctionDeclaration());
+ assert.ok(component.node.id);
+ names.add(component.node.id.name);
+ }
+ },
+ });
+ return [...names].sort();
+}
+
+function isMemoCacheSentinel(node) {
+ return (
+ types.isStringLiteral(node, { value: "react.memo_cache_sentinel" }) ||
+ (types.isTemplateLiteral(node) &&
+ node.expressions.length === 0 &&
+ node.quasis[0]?.value.cooked === "react.memo_cache_sentinel")
+ );
+}
+
+function memoizedFunctionCount(ast) {
+ const functions = new Set();
+ traverse(ast, {
+ CallExpression(path) {
+ const { callee, arguments: args } = path.node;
+ if (
+ types.isMemberExpression(callee, { computed: false }) &&
+ types.isIdentifier(callee.object, { name: "Symbol" }) &&
+ types.isIdentifier(callee.property, { name: "for" }) &&
+ args.length === 1 &&
+ isMemoCacheSentinel(args[0])
+ ) {
+ const component = path.getFunctionParent();
+ assert.ok(component, "memoization must belong to a component");
+ functions.add(component.node);
+ }
+ },
+ });
+ return functions.size;
+}
+
+for (const component of optedInComponents) {
+ test(`${component.name} opts in to React 19 compiler memoization`, async () => {
+ const ast = await transformComponent(component);
+ assert.deepEqual(cachedComponentNames(ast), component.compiledNames);
+ assert.equal(memoizedFunctionCount(ast), component.compiledNames.length);
+ });
+}
+
+test("unannotated interactive homepage components remain uncompiled", async () => {
+ const ast = await transformComponent({
+ name: "LandingPageCopyButton",
+ directory: "src/components",
+ });
+ assert.deepEqual(cacheBindings(ast), []);
+ assert.deepEqual(cachedComponentNames(ast), []);
+ assert.equal(memoizedFunctionCount(ast), 0);
+});
+
+test("compiler file filtering includes only opted-in generated application modules", () => {
+ const { include, exclude } = homepageCompilerOptions();
+ const matches = (filename) =>
+ include.test(filename) &&
+ !exclude.some((pattern) => pattern.test(filename));
+ for (const filename of [
+ "/repo/apps/docs/app/routes/LandingPageIntro.jsx",
+ "/repo/apps/docs/app/routes/LandingPageTrustedBy.jsx?import",
+ "C:\\repo\\apps\\docs\\app\\routes\\LandingPageIntro.jsx",
+ "/repo/apps/docs/src/components/LandingPageIntro.jsx",
+ "/repo/apps/docs/src/components/LandingPageTrustedBy.jsx?import",
+ "C:\\repo\\apps\\docs\\src\\components\\LandingPageIntro.jsx",
+ "/repo/apps/docs/src/components/NavbarPrimary.jsx",
+ "/repo/apps/docs/src/components/NavbarPrimary.jsx?import",
+ "C:\\repo\\apps\\docs\\src\\components\\NavbarPrimary.jsx",
+ ]) {
+ assert.equal(matches(filename), true, filename);
+ }
+ for (const filename of [
+ "/repo/apps/docs/app/routes/LandingPageIntro.res",
+ "/repo/apps/docs/app/routes/LandingPageIntro.mjs",
+ "/repo/apps/docs/app/routes/LandingPageIntro.jsx.map",
+ "/repo/apps/docs/app/routes/TryRoute.jsx",
+ "/repo/apps/guide/app/routes/LandingPageIntro.jsx",
+ "/repo/node_modules/example/apps/docs/app/routes/LandingPageIntro.jsx",
+ "C:\\repo\\node_modules\\example\\apps\\docs\\app\\routes\\LandingPageIntro.jsx",
+ "/repo/apps/docs/src/components/LandingPageIntro.res",
+ "/repo/apps/docs/src/components/LandingPageIntro.jsx.map",
+ "/repo/apps/docs/src/components/Search.jsx",
+ "/repo/apps/docs/src/components/NavbarSecondary.jsx",
+ "/repo/apps/guide/src/components/LandingPageIntro.jsx",
+ "/repo/node_modules/example/apps/docs/src/components/LandingPageIntro.jsx",
+ "\0rolldown/runtime.js",
+ ]) {
+ assert.equal(matches(filename), false, filename);
+ }
+});
+
+test("the shared preset preserves annotation mode and excludes server compilation", () => {
+ const [{ preset, rolldown }] = homepageCompilerOptions().presets;
+ assert.deepEqual(preset().plugins, [
+ [
+ "babel-plugin-react-compiler",
+ { compilationMode: "annotation", target: "19" },
+ ],
+ ]);
+ assert.equal(
+ rolldown.filter.code.test('function Example() { "use memo"; }'),
+ true,
+ );
+ assert.equal(rolldown.filter.code.test("function Example() {}"), false);
+ assert.equal(
+ rolldown.applyToEnvironmentHook({ config: { consumer: "client" } }),
+ true,
+ );
+ assert.equal(
+ rolldown.applyToEnvironmentHook({ config: { consumer: "server" } }),
+ false,
+ );
+ assert.deepEqual(rolldown.optimizeDeps.include, ["react/compiler-runtime"]);
+});
+
+test("the production homepage bundle contains its three compiled components", async () => {
+ const directory = new URL("../../build/client/assets/", import.meta.url);
+ const filenames = (await readdir(directory)).filter((filename) =>
+ /^LandingPageRoute-[^/]+\.js$/.test(filename),
+ );
+ assert.equal(filenames.length, 1, "the production homepage entry must exist");
+ const contents = await readFile(new URL(filenames[0], directory), "utf8");
+ const ast = parseSync(contents, { babelrc: false, configFile: false });
+ assert.ok(ast);
+ assert.equal(memoizedFunctionCount(ast), 3);
+});
+
+test("the production client bundle contains the compiled primary navbar", async () => {
+ const directory = new URL("../../build/client/assets/", import.meta.url);
+ const assets = await Promise.all(
+ (await readdir(directory))
+ .filter((filename) => filename.endsWith(".js"))
+ .map(async (filename) => ({
+ filename,
+ contents: await readFile(new URL(filename, directory), "utf8"),
+ })),
+ );
+ const matches = assets.filter(({ contents }) =>
+ contents.includes("navbar-primary-left-content"),
+ );
+ assert.equal(matches.length, 1, "the production primary navbar must exist");
+ const ast = parseSync(matches[0].contents, {
+ babelrc: false,
+ configFile: false,
+ });
+ assert.ok(ast);
+ assert.equal(memoizedFunctionCount(ast), 3);
+});
+
+test("the production server leaves the annotated components uncompiled", async () => {
+ const contents = await readFile(
+ new URL("../../build/server/index.js", import.meta.url),
+ "utf8",
+ );
+ const ast = parseSync(contents, { babelrc: false, configFile: false });
+ assert.ok(ast);
+ const annotatedComponents = [];
+ traverse(ast, {
+ FunctionDeclaration(path) {
+ if (
+ optedInNames.includes(path.node.id?.name) &&
+ path.node.body.directives.some(
+ (directive) => directive.value.value === "use memo",
+ )
+ ) {
+ annotatedComponents.push(path.node.id.name);
+ }
+ },
+ });
+ assert.deepEqual(annotatedComponents.sort(), [...optedInNames].sort());
+ assert.deepEqual(cacheBindings(ast), []);
+ assert.equal(memoizedFunctionCount(ast), 0);
+});
diff --git a/apps/docs/src/components/LandingPageInstallInstructions.res b/apps/docs/src/components/LandingPageInstallInstructions.res
index f3e4d0562..45bc0cf61 100644
--- a/apps/docs/src/components/LandingPageInstallInstructions.res
+++ b/apps/docs/src/components/LandingPageInstallInstructions.res
@@ -8,18 +8,20 @@ let copyBox = text => {
}
@react.component
-let make = (~className="") => {
-
-
{React.string("Quick Install")}
-
- {React.string(
- "You can quickly add ReScript to your existing JavaScript codebase via npm / yarn:",
- )}
+let make =
+ @directive("'use memo'")
+ (~className="") => {
+
+
{React.string("Quick Install")}
+
+ {React.string(
+ "You can quickly add ReScript to your existing JavaScript codebase via npm / yarn:",
+ )}
+
+ {copyBox("npm install rescript")}
+
+ {React.string("Or generate a new project from the official template with npx:")}
+
+ {copyBox("npx create-rescript-app")}
- {copyBox("npm install rescript")}
-
- {React.string("Or generate a new project from the official template with npx:")}
-
- {copyBox("npx create-rescript-app")}
-
-}
+ }
diff --git a/apps/docs/src/components/LandingPageInstallInstructions.resi b/apps/docs/src/components/LandingPageInstallInstructions.resi
index 193c81cf3..92fce9cea 100644
--- a/apps/docs/src/components/LandingPageInstallInstructions.resi
+++ b/apps/docs/src/components/LandingPageInstallInstructions.resi
@@ -1,2 +1,3 @@
+/** Opt in to React Compiler for the homepage browser build. */
@react.component
let make: (~className: string=?) => React.element
diff --git a/apps/docs/src/components/LandingPageIntro.res b/apps/docs/src/components/LandingPageIntro.res
index 17e368c4d..01767bd75 100644
--- a/apps/docs/src/components/LandingPageIntro.res
+++ b/apps/docs/src/components/LandingPageIntro.res
@@ -1,27 +1,29 @@
@react.component
-let make = () => {
-
-
-
- {React.string("JavaScript Made Simple for Humans and AI")}
-
-
- {React.string(`Types > Vibes`)}
-
-
- {React.string(`ReScript is a strongly typed language that compiles to clean,
+let make =
+ @directive("'use memo'")
+ () => {
+
+
+
+ {React.string("JavaScript Made Simple for Humans and AI")}
+
+
+ {React.string(`Types > Vibes`)}
+
+
+ {React.string(`ReScript is a strongly typed language that compiles to clean,
efficient JavaScript that humans and AI tools can read and understand.`)}
-
-
- {React.string(`Its fast compiler and static type system keep feedback loops tight,
+
+
+ {React.string(`Its fast compiler and static type system keep feedback loops tight,
so you can move quickly with AI assistance while maintaining
confidence as your codebase grows.`)}
-
-
- {React.string("Get started")}
-
-
-
-}
+
+
+ {React.string("Get started")}
+
+
+
+ }
diff --git a/apps/docs/src/components/LandingPageIntro.resi b/apps/docs/src/components/LandingPageIntro.resi
index 26c2771b5..ba814dcb8 100644
--- a/apps/docs/src/components/LandingPageIntro.resi
+++ b/apps/docs/src/components/LandingPageIntro.resi
@@ -1,3 +1,3 @@
-/** Prefetch installation content only after hover or focus intent. */
+/** Prefetch on intent and opt in to React Compiler for the homepage browser build. */
@react.component
let make: unit => React.element
diff --git a/apps/docs/src/components/LandingPageTrustedBy.res b/apps/docs/src/components/LandingPageTrustedBy.res
index 0ee3d8d91..3041a1134 100644
--- a/apps/docs/src/components/LandingPageTrustedBy.res
+++ b/apps/docs/src/components/LandingPageTrustedBy.res
@@ -1,43 +1,45 @@
@react.component
-let make = () => {
- let ourUsersSourcePath = "apps/docs/src/data/OurUsers.res"
+let make =
+ @directive("'use memo'")
+ () => {
+ let ourUsersSourcePath = "apps/docs/src/data/OurUsers.res"
-
-}
+
+ }
diff --git a/apps/docs/src/components/LandingPageTrustedBy.resi b/apps/docs/src/components/LandingPageTrustedBy.resi
index e0905fb23..6a5ddde2e 100644
--- a/apps/docs/src/components/LandingPageTrustedBy.resi
+++ b/apps/docs/src/components/LandingPageTrustedBy.resi
@@ -1,3 +1,3 @@
-/** Company logos retain their intrinsic aspect ratio at the existing display height. */
+/** Retain intrinsic logo ratios and opt in to React Compiler for the browser build. */
@react.component
let make: unit => React.element
diff --git a/apps/docs/src/components/NavbarPrimary.res b/apps/docs/src/components/NavbarPrimary.res
index 5f586b3f5..a8e5d1c6a 100644
--- a/apps/docs/src/components/NavbarPrimary.res
+++ b/apps/docs/src/components/NavbarPrimary.res
@@ -9,119 +9,128 @@ let isActive = (~url, ~pathname: Path.t) => {
module LeftContent = {
@react.component
- let make = () => {
- let {pathname} = useLocation()
-
-
-
-
-
-
- {React.string("Docs")}
-
-
- {React.string("Playground")}
-
-
- {React.string("Blog")}
-
-
{
+ let {pathname} = useLocation()
+
- {React.string("Community")}
-
-
- }
+
+
+
+
+
+ {React.string("Docs")}
+
+
+ {React.string("Playground")}
+
+
+ {React.string("Blog")}
+
+
+ {React.string("Community")}
+
+
+ }
}
module RightContent = {
@react.component
- let make = () => {
- let iconClasses = "w-6 h-6 opacity-50 hover:opacity-100"
- let linkClasses = "hidden md:block"
-
+ }
}
@react.component
-let make = () => {
- let scrollDirection = Hooks.useScrollDirection(~topMargin=64, ~threshold=32)
+let make =
+ @directive("'use memo'")
+ () => {
+ let scrollDirection = Hooks.useScrollDirection(~topMargin=64, ~threshold=32)
- let navbarClasses = switch scrollDirection {
- | Up(_) => "translate-y-0"
- | Down(_) => "-translate-y-full md:translate-y-0"
- }
+ let navbarClasses = switch scrollDirection {
+ | Up(_) => "translate-y-0"
+ | Down(_) => "-translate-y-full md:translate-y-0"
+ }
- <>
-
+
-
-
-
-
- >
-}
+ >
+
+
+
+
+ >
+ }
diff --git a/apps/docs/src/components/NavbarPrimary.resi b/apps/docs/src/components/NavbarPrimary.resi
index 1ca44ce26..6b2d7a887 100644
--- a/apps/docs/src/components/NavbarPrimary.resi
+++ b/apps/docs/src/components/NavbarPrimary.resi
@@ -1,2 +1,3 @@
+/** Shared primary navigation opts in to React Compiler for client builds. */
@react.component
let make: unit => React.element
diff --git a/apps/docs/vite-react-compiler.mjs b/apps/docs/vite-react-compiler.mjs
new file mode 100644
index 000000000..17b320e61
--- /dev/null
+++ b/apps/docs/vite-react-compiler.mjs
@@ -0,0 +1,18 @@
+import babel from "@rolldown/plugin-babel";
+import { reactCompilerPreset } from "@vitejs/plugin-react";
+
+export function homepageCompilerOptions() {
+ return {
+ include:
+ /[/\\]apps[/\\]docs[/\\](?:app[/\\]routes|src[/\\]components)[/\\](?:LandingPage[^/\\]*|NavbarPrimary)\.jsx(?:$|\?)/,
+ exclude: [/[/\\]node_modules[/\\]/, /^\0rolldown\/runtime\.js$/],
+ presets: [
+ // Keep the preset's client-only guard and React 19 runtime optimization.
+ reactCompilerPreset({ compilationMode: "annotation", target: "19" }),
+ ],
+ };
+}
+
+export function homepageReactCompiler() {
+ return babel(homepageCompilerOptions());
+}
diff --git a/apps/docs/vite.config.mjs b/apps/docs/vite.config.mjs
index 9ad4544bb..5a2e93a36 100644
--- a/apps/docs/vite.config.mjs
+++ b/apps/docs/vite.config.mjs
@@ -6,6 +6,7 @@ import { defineConfig } from "vite";
import devtoolsJson from "vite-plugin-devtools-json";
import env from "vite-plugin-env-compatible";
import pageReload from "vite-plugin-page-reload";
+import { homepageReactCompiler } from "./vite-react-compiler.mjs";
const excludedFiles = ["lib/**", "**/*.res", "**/*.resi"];
@@ -24,6 +25,7 @@ export default defineConfig({
include: ["**/*.mjs"],
exclude: excludedFiles,
}),
+ homepageReactCompiler(),
// this is to make it so babel doesn't break when trying to acess process.env in the client
env({ prefix: "PUBLIC_" }),
// adds dev scripts for browser devtools
diff --git a/apps/docs/vitest.config.mjs b/apps/docs/vitest.config.mjs
index 427123952..893c7048f 100644
--- a/apps/docs/vitest.config.mjs
+++ b/apps/docs/vitest.config.mjs
@@ -3,6 +3,7 @@ import { playwright } from "@vitest/browser-playwright";
import react from "@vitejs/plugin-react";
import tailwindcss from "@tailwindcss/vite";
import { responsiveImage } from "@responsive-image/vite-plugin";
+import { homepageReactCompiler } from "./vite-react-compiler.mjs";
const isUpdatingSnapshots = process.argv.some(
(arg) => arg === "-u" || arg === "--update" || arg.startsWith("--update="),
@@ -35,7 +36,7 @@ const setupDeps = [
export default defineConfig({
envDir: "../..",
- plugins: [responsiveImage(), react(), tailwindcss()],
+ plugins: [responsiveImage(), react(), homepageReactCompiler(), tailwindcss()],
optimizeDeps: {
include: setupDeps,
},
diff --git a/yarn.lock b/yarn.lock
index ccb3767be..d9df19e2d 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -224,6 +224,16 @@ __metadata:
languageName: node
linkType: hard
+"@babel/types@npm:^7.26.0":
+ version: 7.29.8
+ resolution: "@babel/types@npm:7.29.8"
+ dependencies:
+ "@babel/helper-string-parser": "npm:^7.29.7"
+ "@babel/helper-validator-identifier": "npm:^7.29.7"
+ checksum: 10c0/be7c279f0abf2a086c633e21b49c7ca80275d05283cc5a268b67a708c9914bd0c944f1422b3eb3cb37682a2af5d560abf520ccf9b01b53ecbfe6b71fbc3fdde6
+ languageName: node
+ linkType: hard
+
"@blazediff/core@npm:1.10.0":
version: 1.10.0
resolution: "@blazediff/core@npm:1.10.0"
@@ -1928,6 +1938,7 @@ __metadata:
version: 0.0.0-use.local
resolution: "@rescript-lang/docs@workspace:apps/docs"
dependencies:
+ "@babel/core": "npm:^7.29.7"
"@cloudflare/pages-plugin-vercel-og": "npm:^0.1.2"
"@docsearch/react": "npm:^4.6.2"
"@headlessui/react": "npm:^2.2.9"
@@ -1941,11 +1952,13 @@ __metadata:
"@rescript/webapi": "npm:0.1.0-experimental-29db5f4"
"@responsive-image/core": "npm:2.1.0"
"@responsive-image/vite-plugin": "npm:3.0.1"
+ "@rolldown/plugin-babel": "npm:^0.2.4"
"@tailwindcss/vite": "npm:^4.3.0"
"@types/react": "npm:^19.2.14"
"@vitejs/plugin-react": "npm:^6.0.1"
"@vitest/browser-playwright": "npm:^5.0.0"
auto-image-converter: "npm:^2.2.0"
+ babel-plugin-react-compiler: "npm:^1.0.0"
chokidar: "npm:^4.0.3"
cypress: "npm:^15.13.1"
cypress-real-events: "npm:^1.15.1"
@@ -1976,6 +1989,7 @@ __metadata:
remark-gfm: "npm:^4.0.1"
remark-validate-links: "npm:^13.1.0"
rescript: "npm:^12.2.0"
+ rolldown: "npm:1.2.8"
search-insights: "npm:^2.17.3"
tailwindcss: "npm:^4"
tinyglobby: "npm:^0.2.15"
@@ -2293,6 +2307,28 @@ __metadata:
languageName: node
linkType: hard
+"@rolldown/plugin-babel@npm:^0.2.4":
+ version: 0.2.4
+ resolution: "@rolldown/plugin-babel@npm:0.2.4"
+ dependencies:
+ picomatch: "npm:^4.0.7"
+ peerDependencies:
+ "@babel/core": ^7.29.0 || ^8.0.0-rc.1
+ "@babel/plugin-transform-runtime": ^7.29.0 || ^8.0.0-rc.1
+ "@babel/runtime": ^7.27.0 || ^8.0.0-rc.1
+ rolldown: ^1.0.0-rc.5
+ vite: ^8.0.0
+ peerDependenciesMeta:
+ "@babel/plugin-transform-runtime":
+ optional: true
+ "@babel/runtime":
+ optional: true
+ vite:
+ optional: true
+ checksum: 10c0/1283804c979f32c24adf3e80177ff3ebb7f8db749660235ed0a511cd4e1a3c129bea4209dee5f9ee67b1709a6efc65986349ca10ff2f5557c86623d1eebd7b42
+ languageName: node
+ linkType: hard
+
"@rolldown/pluginutils@npm:1.0.0-rc.7":
version: 1.0.0-rc.7
resolution: "@rolldown/pluginutils@npm:1.0.0-rc.7"
@@ -3220,6 +3256,15 @@ __metadata:
languageName: node
linkType: hard
+"babel-plugin-react-compiler@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "babel-plugin-react-compiler@npm:1.0.0"
+ dependencies:
+ "@babel/types": "npm:^7.26.0"
+ checksum: 10c0/9406267ada8d7dbdfe8906b40ecadb816a5f4cee2922bee23f7729293b369624ee135b5a9b0f263851c263c9787522ac5d97016c9a2b82d1668300e42b18aff8
+ languageName: node
+ linkType: hard
+
"bail@npm:^2.0.0":
version: 2.0.2
resolution: "bail@npm:2.0.2"
@@ -9390,7 +9435,7 @@ __metadata:
languageName: node
linkType: hard
-"rolldown@npm:~1.2.6":
+"rolldown@npm:1.2.8, rolldown@npm:~1.2.6":
version: 1.2.8
resolution: "rolldown@npm:1.2.8"
dependencies: