BRYME TECH
SEPTEMBER 2026 · THE TOOL DESKPractical technology. No theatre.
THE BRYME

Practical guide · verified against the real thing

Why does it work locally but fail online? The six differences

In one line: Environment, case sensitivity, build-vs-serve, localhost URLs, dependency drift and paths — the gaps between your machine and the internet's.

The symptom: the project runs beautifully on your machine and falls over deployed. This is not bad luck — your computer and a production server are different machines in every way that matters. There are six differences, and they explain nearly every case.

1. Environment variables do not follow you

Your .env file is gitignored (correctly!), so production does not have your keys — the app boots and fails on first use. Or worse, the platform has a stale value from months ago. Fix: list every env var the build and runtime need, set them in the platform's settings, and make the app fail loudly at startup when one is missing. Silent fallbacks to defaults are how wrong-database bugs are born.

2. Case sensitivity

Windows and macOS file systems are case-insensitive by default; production Linux is not. import Header from './header.jsx' works locally over Header.jsx and fails online. The same for images and data files: the case in your code must match the case on disk, exactly. If it "only fails on the server", audit case first.

3. Build versus serve: the baked-at-build trap

Static and front-end frameworks bake environment values at build time, not runtime — setting a variable on the server after building changes nothing. The classic: your production build was made months ago with old values, and no runtime setting can save it. Rebuild after every change, and know which of your values are build-time and which are runtime (the deploy diagnostic covers the publish-directory side of this).

4. Hardcoded localhost

http://localhost:3000/api works on your machine and nowhere else in the universe. Search the codebase for "localhost" before every deploy; configuration belongs in env vars, and same-origin paths (/api/...) beat absolute URLs wherever your architecture allows.

5. Dependency drift

Locally you have whatever installed the month you built the project; production installs from the lockfile — or, without one, whatever is newest today. Pin dependencies, commit the lockfile, and use the same runtime version in CI as on your machine (a .node-version-style file, honoured by the platform).

6. Paths: absolute, relative, and the missing base

Absolute paths (/assets/logo.png) break when the app is served under a sub-path; case-sensitivity (difference #2) compounds it. Relative paths and configured base URLs survive relocation. When assets 404 in production only, this and #2 together are the culprit more often than not.

The honest method

Reproduce production locally once: build in production mode, serve the built output, run with empty env vars — most of these six will reproduce without deploying at all. Then fix them in the order that fails loudest. The payoff is permanent: a project that survives a clean-clone-plus-deploy is a project that deploys calmly forever. Companions: the deployment diagnostic tree and GitHub Pages hiding your changes.

Official documentation (checked 11 September 2026): your framework's environment-variables guide (Vite, Next.js and Create React App all document build-time vs runtime values), and the Twelve-Factor App's config principles (12factor.net) — the difference between your laptop and the internet, formalised.

Next

Related on this desk.