Devlog · Phase 0 · 2/7
The aubia.dev Stack: Octane, FrankenPHP, and Inertia SSR
Latency cut five to ten times with Octane and FrankenPHP, an Inertia SSR that serves the full HTML from the first byte: the aubia.dev stack, block by block.
- laravel
- octane
- frankenphp
- inertia
- vite

aubia.dev serves its full HTML from the first byte and responds with latency cut five to ten times compared to classic PHP-FPM. For a landing page, that's no luxury: a marketing site has one non-negotiable job, to be seen. By visitors, but first by search engines and by AI answer engines. Let me open up the stack, with the reasoning behind each block.
Server-Side Rendering as an SEO Invariant
A classic React app returns an empty HTML shell, then populates the page in JavaScript. A browser copes with that. A crawler or an answer engine, on the other hand, has to find the content directly in the HTML of the first response.
That's why I ruled out client-only rendering on this website. Here SSR commands everything else. Inertia v3 renders the React pages on the server, and the full HTML goes out from the first byte: the title, the subtitle, the sections, the SEO metadata, everything is present before a single line of JavaScript runs on the client. Hydration then takes over for interactivity. This rule, content must exist in the initial HTML, dictates everything else in the frontend code, down to the ban on rendering content through a useEffect.
Octane and FrankenPHP: the Server That Never Restarts
I installed Octane on day one of the repo, in late April 2026, before writing a single line of content. It's a foundation choice, not an optimization bolted on afterward. In traditional PHP, every request reboots the application: loading the framework, resolving the container, then responding. Laravel Octane changes that model. The application boots once, then persistent workers serve thousands of requests within the same process.
That left the driver to choose. I looked at RoadRunner and Swoole, Octane's two other options, before settling on FrankenPHP: it embeds the Caddy server natively, with HTTP/3, automatic certificates, and streaming with no extra layer to operate, and its roadmap is active in the Laravel ecosystem.
// config/octane.php
'server' => env('OCTANE_SERVER', 'roadrunner'),
# .env : le driver actif sur aubia.dev
OCTANE_SERVER=frankenphp
On this foundation, the Laravel bootstrap stays in memory and per-request latency drops by a factor of five to ten compared to PHP-FPM's cold start. A low, stable server response time counts toward the performance score, and therefore toward ranking. But this model imposes a discipline I'll get to below.
Inertia v3: React Without a Separate API
The thing that makes this stack pleasant is Inertia. It bridges Laravel and React without my having to build and version a separate REST API. Controllers return React pages with their props, the same way they'd return Blade views. SSR is enabled in the configuration, with no separate Node server to maintain in development.
// config/inertia.php
'ssr' => [
'enabled' => true,
'url' => 'http://127.0.0.1:13714',
],
Concretely, Inertia::render() replaces the views, the routes stay defined on the Laravel side, and React only worries about rendering. A single source of truth for routing, no logic duplicated between a back end and a front end that ignore each other.
Vite 8, Rolldown, and React 19
On the build side, aubia.dev uses Vite 8 with Rolldown, the Rust-written bundler integrated natively. React 19 is compiled with the React Compiler, which automatically memoizes components without manual annotations. Bundle splitting is driven explicitly to isolate the heavy dependencies into their own chunks:
// vite.config.ts
codeSplitting: {
minSize: 20_000,
groups: [
{ name: 'react', test: /node_modules\/(react|react-dom|scheduler)\//, priority: 50 },
{ name: 'motion', test: /node_modules\/(motion|motion-dom)\//, priority: 40 },
{ name: 'fontawesome', test: /node_modules\/@fortawesome\//, priority: 30 },
],
},
Separating React, the animations, and the icons lets the browser cache what rarely changes and reload only what does. The production build also generates a dedicated SSR bundle via vite build --ssr.
The Stateless Constraint
A server that never restarts keeps everything in memory between requests. That's exactly what makes it fast, and it's also its trap. Under Octane, storing request-specific state in a singleton or a static property would leak it into the next request, served by the same worker. So all the website's code respects this rule: no request state is held beyond its scope.
The waitlist count, for instance, is loaded lazily so the server render doesn't block on a network call, and its result arrives in a second request on the client side:
'waitlist' => [
'count' => Inertia::defer(fn(): ?int => app(FetchWaitlistCountQuery::class)->run()),
],
The SSR stays instant this way, and the non-deterministic data never enters the first render. This stateless rigor runs through every module in the repo.
What Speed Doesn't Yet Tell
Octane, FrankenPHP, and Inertia give a fast, indexable website. This restraint goes further still: the next step removes the database itself, and with it all local storage of personal data.
To be notified when the beta 0.1 opens, join the waitlist.
This build is chronicled here, article after article. Come aboard: your feedback will shape what comes next.
Join the waitlist