I wanted the same todo app built twice. People call this science; I call it
doing my homework twice. I set the spec — magic-link auth, projects, due dates,
five views, identical UX — and Claude wrote both versions. One is 621 lines in a
single PHP file. The other is 1,275 lines across five files using Bun, Hono,
React 19, Drizzle, Vite, TypeScript, and Tailwind via CDN — the same Tailwind
setup as the PHP version. Then we compared them.
Live: todo-app-php ·
todo-app-js.
The numbers
Metric
PHP
JS
Lines of code
621
1,275
Files (code)
1
5
Dependencies
0
78+ direct (379 in node_modules)
Build time
0 s
~10 s
Deploy time (from push)
~5 s
~30–60 s
Docker image size
~30 MB
~150 MB
Memory at runtime
~20 MB
~140 MB
First paint
1 round-trip
3 round-trips
Cold start
<100 ms
~500 ms
PHP single file
no framework · no build · 1 file
Pros
No build step
No dependencies
Deploy = git pull
Iteration: edit → save → refresh
Runs on $1/mo shared hosting
No npm audit, no supply chain attacks
One mental model (1 file)
Junior dev gets it in an hour
No dependency upgrades that break the app
Zero state management bugs (everything in DB)
Always fresh data (full reload)
SEO friendly out of the box
7× less memory, 5× smaller image
Pieter Levels makes $2M+/year this way
Cons
No type safety
Hard to test (global state, refactor first)
Page reload on every action (300–500 ms blink)
No optimistic UI
Migrations run on every request
Without a framework, larger apps fall apart
No free API for mobile clients
Single-threaded php -S for dev (need php-fpm for prod)
Levels.io style has "amateur" reputation
Large refactors mean grepping everywhere
Hurts past ~3,000 LOC
No autocomplete for DB row fields
JavaScript stack
Bun · Hono · React 19 · Drizzle · Vite · TypeScript
Pros
Type safety end-to-end (Drizzle generates types from schema)
Optimistic UI, drag & drop, animations
Real-time features easy (WebSocket, SSE)
REST API for free (mobile, browser extensions can consume it)
Smooth UX, no page reloads
More testable (clear server/client split, pure functions)
Migrations run once on boot
IDE autocomplete for every DB field
Safer large refactors
Bun is a fast runtime
React has a massive community
Same language frontend and backend
Scales better for teams
Cons
2× more code for the same functionality (after dropping custom CSS)
Build pipeline (Vite, esbuild, plugins) = more things that can break
Dep upgrades break things (React 19, Tailwind 4, Vite 7 — all breaking)
npm audit + Dependabot maintenance overhead
80+ packages = 80+ maintainers you have to trust
7× more memory
5× larger Docker image
Deploy needs build step + container restart
3 round-trips before first paint
8 useState hooks in one component → state bugs
HMR sometimes drops, restart the dev server
Onboarding a new dev takes hours (Node? Bun? cache?)
Shared hosting unusable — VPS minimum
SPA has worse SEO without SSR
Sometimes fight TS with as or ! to silence the compiler
Why 3 round-trips on JS?
I asked why the JS version takes longer to show the first screen. The answer
is simple. A single-page app can't render the first useful screen until it knows
who you are and what to show you. Those two questions are
sequential — you can't ask the second until the first returns.
JS waterfall
0 ms GET /
→ empty <div id="root"></div> shell
50 ms parse HTML, fetch /assets/*.js + *.css
250 ms React mounts, useEffect fires
GET /api/auth/me — "who am I?"
350 ms auth resolves, next useEffect fires
GET /api/state?view=today — "what should I show?"
450 ms USER SEES UI
PHP timeline
0 ms GET /
→ server reads session, queries DB, renders full HTML
100 ms USER SEES UI
PHP is fast because the server already knows everything. The browser only
has to draw what arrives in the first response. SPAs can match this with
SSR + streaming + inline state — but that's hundreds of lines of extra
setup. Server-rendered HTML gives you the same result for free. Claude wrote
both versions, so I can say this without taking sides: one of them was more
work for a slower first paint.
When to pick which
Pick PHP single file when
You're a solo developer
It's a side project or hobby
You want to ship an MVP in a week
Indie SaaS with low–mid traffic
Internal tools, admin panels
Hosting on the cheapest VPS
You want to ship today
Minimal maintenance for years
"Form submit + reload" UX is acceptable
Pick JavaScript stack when
Team of 2+ developers
Planning a mobile app over the same API
Real-time or collaborative features
Drag & drop, rich UI interactions
App with a 5+ year lifespan
UX matters (animations, instant feedback)
You have time and energy for the dep tree
Here is where I landed. The JavaScript stack solves problems
most solo projects don't have. PHP single file is a tool proportional
to the size of most projects. Pieter Levels isn't right because
"PHP is best" — he's right because he picks tools by
project size, not by hype.