Hosting a React App in 2026: From DevOps Project to Git Push

The first time I deployed something to production, it took a week and a person whose entire job was making deployments happen. There was a server to configure, a pipeline to wire, environment variables to get wrong in six interesting ways, and a deploy checklist that read like a pre-flight sequence. Shipping was an event.
The last thing I deployed took a git push. No server, no pipeline I wrote, no checklist. I pushed to main, and a minute later it was live with a URL and HTTPS I didn't configure. Same person, same nervousness the first time — and almost none of the work.
That compression is the story of modern hosting, and it's easy to take for granted until you realize it quietly changed who gets to ship things. When deployment stops being a discipline, a single developer can put a real, full-stack app in front of real users without a DevOps team standing behind them. So this article is about how to think about hosting a React app now — not a tutorial for one platform, but the mental model, the tiers, and the place where the magic politely stops.
First, What Are You Actually Deploying?
The most common hosting confusion isn't about platforms. It's that "deploy my React app" means two completely different things depending on what you built, and picking the wrong kind of host is where people get stuck.
A static site. If your app is client-side rendered or statically generated — this very blog is a static export — then "deploying" is just serving files. HTML, CSS, JS, sitting on a CDN. There's no server running your code; there's a very fast file server near your users. This is the cheapest, simplest, most durable thing you can ship, and platforms like GitHub Pages, Netlify, Cloudflare Pages, and Vercel do it beautifully, often free.
An app with a server. The moment you have SSR, server functions, or a backend and database, there's actual code that has to run on demand, somewhere, all the time. That's not a file server. That's a running process, and it needs a host that keeps it alive, scales it, and gives it access to your database.
Almost every hosting mistake I see is someone trying to fit one of these into the other's home — pushing a full-stack app onto a static-only host and wondering why the server code never runs, or paying for an always-on server to deliver what is really just a folder of files. Know which one you have first. Everything else follows from that.
The Static Path: Basically Solved
If you're shipping a static site, the good news is you barely have to think. Connect your Git repo to Netlify, Cloudflare Pages, Vercel, or GitHub Pages; every push to your main branch builds and deploys automatically; you get a global CDN, HTTPS, and preview URLs for pull requests without configuring any of it.
This series' own site is the proof — a Next.js static export pushed to a branch, built by CI, served from a CDN, on a custom domain. There is no server. There is nothing to keep running. And that's exactly why it's the most robust option: the thing that can't crash at 3am is the thing that isn't running. If your app can be static, let it be static, and enjoy how little there is to worry about.
The Full-Stack Path: Where Railway Comes In
The interesting decisions start when you have a server to run. Now you need a platform that takes your code, containerizes it, keeps the process alive, connects it to a database, manages environment variables and secrets, and scales it when traffic climbs — all without you learning Kubernetes.
This is the category Railway lives in, alongside Render, Fly.io, and the more serverless-shaped Vercel functions model. What they share is the same compression that hit static hosting, now applied to running servers: you connect a repo, and a git push builds and deploys a live process.
# The entire "deploy a full-stack app" story, conceptually: git push # push to the connected branch # platform detects the app, builds a container, # injects env vars, runs it, gives it a URL and HTTPS
What I like about this generation of platforms is that they collapse the app and its dependencies into one place. On Railway you can provision your database right next to your app and wire them together in the dashboard, so the Turso-or-Postgres decision from the last article and the hosting decision stop being two separate projects. The whole backend — process, database, environment — lives in one connected picture instead of a pile of services you glued together by hand. For a solo developer or a small team, that consolidation is the actual product.
I'm not going to crown one winner. Railway is excellent for full-stack apps that want a database and a server in one tidy place; Fly.io leans toward running close to users at the edge; Vercel is the smoothest possible home for a Next.js app specifically. The right pick depends on your stack, and the honest advice is to match the platform to the shape of what you built, not to the loudest brand.
Environment Variables: The One Thing to Get Right
If there's a single operational skill that separates a smooth deploy from a painful one, it's handling configuration correctly — and it's where security quietly rides along.
The rule is simple and non-negotiable: secrets go in the platform's environment variables, never in your code, never in your repo. Your database URL, your auth tokens, your API keys — those live in Railway's (or whoever's) settings, injected into the process at runtime.
And there's a React-specific trap worth calling out, because it burns people. Anything your frontend bundle can read is public — it ships to the browser, where anyone can open it and look. Frameworks make this explicit with prefixes: a variable exposed to the client is deliberately marked as such.
# Safe on the server only — never reaches the browser: DATABASE_URL=... AUTH_SECRET=... # Deliberately public — bundled into the client, so treat as visible: NEXT_PUBLIC_ANALYTICS_ID=... VITE_PUBLIC_APP_URL=...
That prefix is a security boundary, not a naming convention. A secret with a public prefix is a secret you've published. This connects straight back to the authentication article: the same discipline of knowing what the browser can and cannot see applies to every environment variable you set. Get this one habit right and you've avoided the most common way small teams leak credentials.
Where the Magic Stops
I've spent this article celebrating how easy hosting got, so let me be honest about where the smooth part ends, because pretending it doesn't is how people get surprised.
Auto-scaling is real, but it isn't free or infinite — traffic spikes cost money, and a runaway process or a bad loop can run up a bill while you sleep. Cold starts are real on serverless tiers: a function that hasn't run in a while takes a beat to wake, and for some apps that latency matters. Databases have connection limits that serverless functions, which spin up many instances, can exhaust in ways that surprise you. And "it deployed" is not "it works" — you still own monitoring, logging, and knowing when production is unhappy.
None of this brings back the week-long deploy. It just means the modern platform moved your attention from how do I ship this to how does this behave once it's shipped, which is a much better problem to have. The floor got higher. The ceiling is still yours to worry about.
The Takeaway
Boil it down:
- Know what you're deploying. Static site or running server — that single fact chooses your host.
- If it can be static, let it be static. The cheapest, most durable option is the one with nothing running.
- For full-stack, use a platform that consolidates app and database. Railway, Render, Fly.io — a git push to a live process, database next door.
- Secrets in env vars, and respect the public prefix. It's a security boundary, not a style choice.
- The magic stops at runtime behavior. Scaling cost, cold starts, connection limits, monitoring — still yours.
I started this series' thread on infrastructure by admitting the database used to scare me. Hosting used to scare me for the same reason — it looked like a separate profession guarding the door to production. It isn't anymore. The tools compressed a week of DevOps into a git push, and that didn't just save time; it moved the power to ship real software into the hands of individual developers. You can build the app, store its data, and put it in front of the world, alone, in an afternoon. That's genuinely new, and it's worth not taking for granted.
The app is built, stored, and deployed. Now we make sure it stays working — the next article is about testing in React: the kinds of tests, the pain each one actually removes, and how to test without drowning in brittle suites.
If you've got an app that's stuck at the "how do I actually put this online" step, that used to be a wall and now it's a git push — tell me what you built and I'll point you at where it should live.