Community JavaScript Snippet
Four Things I Forget About Create-React-App Every Year
Cheat sheet for the CRA quirks that keep coming back. Absolute imports via jsconfig, the HTTPS dev flag, the registerServiceWorker mystery, and the REACT_APP_ env var rules.
Four Things I Forget About Create-React-App Every Year
Cheat sheet for the CRA quirks that keep coming back. Absolute imports via jsconfig, the HTTPS dev flag, the registerServiceWorker mystery, and the REACT_APP_ env var rules.
By @yunatorres
March 29, 2026
·
Updated July 4, 2026
308 views
6
4.3 (13)
Two minutes of config that ages well. The whole behaviour is one line: compilerOptions.baseUrl: 'src' in jsconfig.json (or tsconfig.json for TS projects), and CRA picks it up on the next dev-server start. Every import becomes rootable from src/, so a file three levels deep does not have to count ../../../. The two gotchas worth flagging are that the paths field for arbitrary aliases is not supported by CRA without ejecting or react-app-rewired, and that VS Code uses the same jsconfig.json for autoimport, so once you add it your tooling stops suggesting relative paths and quietly switches to the absolute ones. Modern bundlers (Vite, esbuild) handle this with resolve.alias; CRA's path is the JSON file.
I always forget which variable controls which behaviour, so the cheat sheet lives in this snippet. HTTPS=true is the only one most people need; the cert files matter the moment you want a green padlock or a real subject name on the cert (mobile testing on a LAN IP is the usual reason). mkcert is the easy path for local CA generation: install once, generate per-project certs, point CRA at them with SSL_CRT_FILE and SSL_KEY_FILE. The unintuitive bit is why you would bother in dev: cookies with Secure get dropped by the browser over http://localhost, so an auth flow that works in production silently fails in dev unless HTTPS is on. The same bites you with service workers, third-party SDKs, and anything that gates on window.isSecureContext.
The shape of this part of CRA is a lot more interesting than it sounds. The repo ships with the wiring for an offline-first PWA, but ships with it disabled because the offline-first cache strategy has burned more teams than it has helped. The kill-switch at the bottom is the most useful piece: if you inherit a project where users still see stale UI weeks after a deploy, it is almost always because an old service worker is precaching the old bundle. The two-line getRegistrations + caches.delete snippet drops into a fresh deploy and clears it on the next visit. If you actually want PWA behaviour, the modern recommendation is Workbox or vite-plugin-pwa; CRA's bundled worker is a 2018 design that did not age well.
Three rules cover almost every CRA env-var question. First, the prefix: REACT_APP_ (or the two specials NODE_ENV and PUBLIC_URL) is what gets inlined into the bundle, everything else is invisible. Second, the cascade: .env.development.local beats .env.development beats .env; the .local files are gitignored by CRA convention so personal overrides do not leak into the repo. Third, the rebuild gotcha: env vars are baked into the bundle at build time, not read at runtime, so a config change after yarn start requires a server restart in dev or a fresh yarn build in CI. The runtime-config alternative at the bottom is the escape hatch: ship a single build artifact, serve a tiny /config.json per environment, fetch it on boot, and you get same-bundle-multi-env without rebuilding.
