LocalCORS
Extension Actions
Fix CORS on localhost. Survives page refresh, HMR reconnect, and service-worker respawn. Never touches YouTube.
CORS errors on localhost shouldn't disappear on refresh — or die when you close
Chrome.
LocalCORS is a developer-first CORS extension scoped to localhost + 127.0.0.1
by default. It uses declarativeNetRequest dynamic rules that Chrome persists
across service-worker eviction, browser restart, and Chrome update — so the
rules you set once stay set. Forever. No heartbeat hacks, no cold-start
re-arming, no mystery re-toggles.
It does one thing and does it correctly.
---
THE SURVIVE-REFRESH WEDGE
Every other CORS extension silently fails the first 60 seconds of real dev.
- "it automatically turns off if I refresh any page"
— carolrizzi, CORS Unblock GitHub issue #24 (open 11+ months)
- "do not work localhost:3000"
— Jake Grabowski, Allow CORS, 1-star
- "An addon should not require my email address to do its job"
— Firefox user 14110808, reviewing Moesif's email-gated advanced settings
LocalCORS fixes every one of these by design, not by patch:
1. DYNAMIC rules, not session rules. Chrome persists them across the ~30s
service-worker idle timeout, browser restart, and Chrome update. The
incumbents use session rules (which die with the service worker) or a
25-second heartbeat alarm — but Chrome 120+ clamps alarms to a 30-second
minimum, meaning the "heartbeat" fires AT the eviction boundary, not
before it.
2. LOCALHOST-SCOPED by default. The manifest declares explicit
http://localhost/* + https://localhost/* + http://127.0.0.1/* +
https://127.0.0.1/* host permissions. YouTube, Gmail, your bank, your
company intranet — all physically out of scope. Adding a staging host
is an explicit, visible runtime grant.
3. CORRECT CREDENTIALED-CORS HANDLING. When the browser sends cookies, we
set Access-Control-Allow-Origin to the exact request origin (scheme +
host + port) — never "*". Setting "ACA-O: *" alongside
"credentials: include" is spec-illegal; the browser silently drops the
response, and every incumbent ships that bug.
---
FEATURES
- Per-tab badge that reads "ON" when the extension is active for the
current host. Zero guessing.
- Per-host on/off toggle in the popup — one click to enable for
localhost:3000, keep it disabled for localhost:4000.
- Options page with an enabled-host table, import / export JSON config,
master switch, and reset-to-defaults.
- Preflight OPTIONS requests handled out of the box with
Access-Control-Allow-Origin + Access-Control-Allow-Methods echo +
status-200 override. No extra toggle.
- Dynamic rule application is mutex-serialized internally, so rapid
toggles (enable localhost, then 127.0.0.1, then disable, all in 2
seconds) apply in order instead of racing.
- Light-and-dark-mode UI matching Chrome's own theme.
FREQUENTLY ASKED
Q: Will this break YouTube?
A: No. LocalCORS is scoped to localhost/*, 127.0.0.1/*, and *.local/*
at install time. YouTube, Gmail, and your company intranet are all
out of scope by default. If you want to enable rules for another
host, it's an explicit, visible action in the popup — not a silent
<all_urls> default.
Q: Why not just run Chrome with --disable-web-security?
A: That flag disables ALL origin protection for the whole browser —
it doesn't just lift CORS. You lose HTTPS cookie isolation, same-site
cookies, the Intelligent Tracking Prevention tooling, and safety on
every tab you have open. Fine for a disposable profile, but terrible
for your actual dev browser where you're also logged into GitHub,
staging admin panels, and your bank. LocalCORS lifts CORS only, only
on hosts you've opted in, and leaves every other security feature
intact.
Q: How does LocalCORS handle the MV3 service-worker respawn?
A: Dynamic rules persist across SW eviction and browser restart —
Chrome guarantees this. Our service worker only re-registers rules
when you change settings. No heartbeat, no alarms, no periodic
wake-up hacks. The incumbents mostly use session rules (which vanish
with the SW), broken 25s alarms (Chrome clamps alarms to a 30s
minimum since Chrome 120, so they fire AT the eviction boundary, not
before), or abandoned static manifest rules — all of which produce
the CORS Unblock issue #24 failure pattern.