Skip to content

Document the frontend migration options - #28

Merged
playforge-coding merged 2 commits into
core-remaining-libfrom
docs-sveltekit-migration
Aug 7, 2026
Merged

Document the frontend migration options#28
playforge-coding merged 2 commits into
core-remaining-libfrom
docs-sveltekit-migration

Conversation

@playforge-coding

@playforge-coding playforge-coding commented Aug 6, 2026

Copy link
Copy Markdown
Owner

Stacked on #27. Documentation only.

Renames sveltekit-migration.mdfrontend-migration.md and restructures it as a decision record rather than a plan for one framework: what phase 1 established, the SSR boundary (framework-independent), four options with their real costs, and what two spikes actually showed.

The finding that changed the recommendation

I'd claimed Solid's advantage over SvelteKit was that you keep Rsbuild — one package, two entries, no toolchain churn. The spike disproved it.

@rsbuild/plugin-solid 1.2.2 did not transform JSX under @rsbuild/core 2.1.10, in a shared config or a dedicated one. Output was React's JSX runtime both times:

(0,n.jsxs)(g,{onClick:()=>i(r()+1),children:["clicked ",r()]})   // shared config
React.createElement(v,{onClick:()=>t(e()+1)},"clicked ",e())      // solid-only config

rsbuild inspect showed no babel loader in the resolved Rspack config — the plugin is silently a no-op. Scoping pluginReact with exclude did not hand the file over. Peer ranges are compatible, so this looks like a v1-era plugin against the v2 plugin API rather than a hard incompatibility, but I could not resolve it.

vite 8.2.0 + vite-plugin-solid 2.11.14 compiled the identical source correctly — Solid's template/insert output with getter-based props.

Consequence: a Solid app needs Vite today, so it lands on the same two-package, two-build-tool, route-split shape as SvelteKit. oxfmt/oxlint are still preserved, since .jsx stays .jsx — that advantage survives.

Kept from the SvelteKit spike

A +page.server.js importing @spelling-creator/core/users server-rendered real data with no JavaScript executed, and no browser-tier module leaked into the server bundle — so the core/browser/* split holds under a real SSR build, not just under the lint rule.

Also recorded

  • The SSR boundary, with the finding that / has nothing data-driven to render (all four fetches auth-gated or DOMParser-based).
  • SSR replaces the crawler prerender but not the /og-image screenshots; Satori + @resvg/resvg-wasm is the replacement, at the cost of embedded fonts and a designed card rather than a screenshot.
  • The measured Solid conversion surface: 59 files, 189 useState, 107 destructured props, 70 .map(), 44 router sites, and 58 forwardRefs that disappear.
  • The failure mode that needs a review rule: destructuring a prop in Solid doesn't error, it silently stops updating.

Verification

pnpm lint, pnpm build:docs pass; the page builds and the overview link is updated. No stale references to the old filename. Lockfile untouched.

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 1de0761c-3039-44dc-90d7-9bc5e90fad95

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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

Records the phases, the SSR boundary and what the spike established, so the
decision is reviewable rather than living in a conversation. Framed as a proposal
throughout — phase 1 stands on its own merits, everything after it is contingent
on a redesign actually happening.

Notes two things the plan got wrong on the first pass. SSR replaces the crawler
prerender but NOT the /og-image screenshots, which are a separate use of Browser
Rendering and a feature loss if simply deleted; Satori + resvg-wasm is the
intended replacement, at the cost of embedded fonts and a designed card rather
than a screenshot. And the homepage has nothing data-driven to server-render:
all four of its fetches are auth-gated or DOMParser-based.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@playforge-coding
playforge-coding force-pushed the docs-sveltekit-migration branch from ff32a77 to 8af8b64 Compare August 6, 2026 01:10
Renames sveltekit-migration.md to frontend-migration.md and restructures it as a
decision record rather than a plan for one framework: what phase 1 established,
the SSR boundary (which is framework-independent), four options with their
costs, and what two spikes actually showed.

Records a negative result worth keeping. @rsbuild/plugin-solid 1.2.2 did not
transform JSX under @rsbuild/core 2.1.10 — in a shared config or a dedicated
one — emitting React's JSX runtime instead, with no babel loader in the resolved
Rspack config. Vite with vite-plugin-solid compiled the identical source
correctly. So a Solid app needs Vite today, which removes the "keep your build
config, one package, two entries" advantage Solid otherwise had over SvelteKit
and lands it on the same two-package shape. oxfmt/oxlint are still preserved,
since .jsx stays .jsx.

Also keeps the SvelteKit spike's positive findings: a +page.server.js can import
@spelling-creator/core/users directly and server-render it with no JavaScript
executed, and no browser-tier module leaks into the server bundle.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@playforge-coding playforge-coding changed the title Document the SvelteKit migration plan Document the frontend migration options Aug 6, 2026
@playforge-coding
playforge-coding merged commit e5628ca into master Aug 7, 2026
1 check passed
@playforge-coding
playforge-coding deleted the docs-sveltekit-migration branch August 7, 2026 00:01
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