Capture fetch/XHR calls on any page, edit them, and refetch — without opening
DevTools. Lives in Chrome's side panel so it stays open while you browse.
With git:
git clone https://github.com/STONE-ROHIT/refetch.git
Without git: on the GitHub repo page, click the green Code button → Download ZIP → unzip it.
Either way, then:
- Open
chrome://extensions - Turn on Developer mode (top right)
- Click Load unpacked → select the
extension/folder — the one withmanifest.jsondirectly inside it, not the project root - Click the toolbar icon to open the side panel
No build step, nothing to npm install. That's the whole setup.
Chrome extensions can't see a page's real fetch/XMLHttpRequest from a
normal content script — so this uses a two-script split:
src/capture-main.js— injected into the page's own JS context ("world": "MAIN"). Monkey-patcheswindow.fetchandXMLHttpRequestto record method/url/headers/body and, once it resolves, status/headers/body. It has nochrome.*access from here.src/capture-bridge.js— a normal isolated-world content script sitting next to it. Relays captured events from the page to the extension viawindow.postMessage→chrome.runtime.sendMessage, and relays refetch commands the other direction.src/background.js— the service worker. Stores history inchrome.storage.local, broadcasts live updates to the side panel, and routes refetch requests to the right tab.src/sidepanel/— the UI. Plain HTML/CSS/JS, no build step, no framework — edit a file and reload the extension to see the change.
Refetch replays through the page, not the extension. When you hit Refetch,
the edited request gets posted back into capture-main.js, which calls
window.fetch(...) itself — so it goes out with the page's own cookies,
session, and CORS context, exactly like the original call would. It also
means every refetch shows up as a fresh entry, since it flows through the same
capture path.
No license key, no account, no tiers. Capture, refetch, the JSON viewer,
copy-as-cURL, pinning, and the {{VAR_NAME}} env vault are all available to
everyone, with one shared 300-request history.
Refetch asks for access to every page to do its job — the same category of permission Postman Interceptor, Requestly, and ModHeader all need — and Chrome will show you its scariest permission warning for it. Fair to be cautious about that, so here's what's actually true:
- No backend. Nothing in this project has ever called out to a server
anyone controls. Captured requests are read from the page and written
straight to
chrome.storage.local, on your own machine, full stop. - No analytics, no telemetry, no dependencies. It's ~10 plain
JS/HTML/CSS files, no build step, no minification, nothing installed from
npm. Everything that runs in your browser is sitting in
extension/srcexactly as written — readable top to bottom in about 15 minutes. - History is public. The commit log shows how it was actually built, not just the end state.
- The
<all_urls>permission (see above) means slower Chrome Web Store review if you eventually submit there — expect that friction, it's normal for this category. - Bump
manifest.json'sversionon every release; the Web Store rejects re-uploads that don't increment it. - The icons in
extension/icons/are generated placeholders (see the retry arrow mark) — swap them for your own before shipping if you want a different visual identity.
MIT — see LICENSE. Use it, fork it, ship your own version.
LICENSE
extension/ ← load this folder unpacked in Chrome
manifest.json
icons/
src/
background.js service worker
capture-main.js MAIN-world page patch (fetch/XHR)
capture-bridge.js isolated-world relay
lib/ storage, cURL export, JSON viewer
sidepanel/ the UI (index.html / style.css / app.js)