Fetcher is a lightweight REST API client for sending HTTP requests, inspecting responses, and keeping a local history of work in progress. It is aimed at developers who want a fast, browser-based alternative to desktop tools like Postman or Insomnia, without accounts, workspaces, or heavy setup.
The app runs in the browser. By default, outbound calls go through a small server proxy so you can exercise APIs without browser CORS limits. You can also send requests directly from the browser when you want to hit same-origin APIs or debug CORS behavior. Request bodies, headers, and query parameters are edited in a Monaco-based UI on a single page.
Use Fetcher when you need to:
- Probe an API — pick a method, enter a URL, and send a request to see status, headers, and body.
- Work around CORS or test it — send via server (proxied) or from browser (native
fetch, subject to CORS). - Iterate on payloads — edit JSON request bodies with syntax highlighting and a Monaco-based editor.
- Tune headers and query params — manage key/value rows, including optional hidden values and masked fields for sensitive data.
- Resume work later — save requests in the sidebar (or the mobile history modal); each snapshot stores the full request state encoded in the page URL.
- Share or bookmark a request — copy a share link (hidden rows omitted, masked values redacted) or a full link (exact address bar URL); method, URL, headers, params, and body live in query parameters so the same setup can be reproduced.
- Reuse a request elsewhere — copy the current setup as JavaScript
fetchor cURL from the session actions. - Document a request — open the Documentation view to see method, URL, and field tables for params, headers, and body with inferred types and example values.
Fetcher is intentionally scoped: it focuses on request construction, execution, and inspection, not collections, environments, or team collaboration.
- HTTP methods:
GET,POST,PUT,PATCH,DELETE,HEAD, andOPTIONS - Send via server or send from browser (dropdown on the submit control; last choice persisted in
localStorage) - Request editor with URL validation
- Tabs for Headers, Params, and Body (body enabled for methods that accept one)
- Read-only response panel backed by the same editor component
- Resizable split between request options and response
- Saved requests in
localStorage, keyed off URL search state, with method badges and active-session highlighting - Session actions: Copy (as JS or cURL), Share link / Share full link, Documentation, New request, and Saved requests (history modal on small screens)
- Request documentation page at
/doc, driven by the same URL query state as the main editor - Installable web app via
manifest.webmanifest, app icons, and theme color for standalone use - Responsive layout: persistent sidebar on larger viewports; compact header actions and history modal on mobile
- Server-side proxy at
POST /api/v1/http-requestfor proxied outboundfetch - Health check at
GET /api/health
| Layer | Choices |
|---|---|
| Framework | Astro (SSR, Vercel adapter) |
| UI | React islands, Tailwind CSS |
| State | Nanostores |
| Editor | Monaco Editor |
| Testing | Playwright (Chromium, e2e/) |
| Utilities | @maxigarcia/js-utils |
- Node.js with a current LTS release
- npm (or another client compatible with
package-lock.json)
git clone https://github.com/MaxiGarcia13/fetcher.git
cd fetcher
npm install
npm run devOpen the URL printed in the terminal (Astro defaults to http://localhost:4321).
npm install registers a pre-commit hook (via simple-git-hooks) that runs ESLint with auto-fix on staged files.
npm run test:e2e starts the dev server when needed (or reuses one already on port 4321 outside CI), installs the Playwright Chromium browser if missing, and runs specs under e2e/. Test output goes to test-results/; the HTML reporter writes playwright-report/ (both are gitignored). Use npm run test:e2e:ui to step through tests interactively.
| Command | Description |
|---|---|
npm run dev |
Start the development server |
npm run build |
Production build |
npm run preview |
Serve the production build locally |
npm run lint |
Run ESLint |
npm run lint:fix |
Run ESLint with auto-fix |
npm run clean |
Remove build artifacts and dependencies |
npm run phoenix |
Clean install from scratch |
npm run test:e2e |
Install Chromium (if needed) and run Playwright end-to-end tests |
npm run test:e2e:ui |
Same as test:e2e, with the Playwright UI for debugging |
- The UI keeps request state in Nanostores and mirrors it into the browser URL query string.
- Send runs the request using the selected mode (stored in
localStorage):- Via server — the client
POSTs the composed request to/api/v1/http-request; that route calls the target URL with the chosen method, headers, query string, and JSON body when applicable, then streams the response back. - From browser — the client calls the target URL with
fetchdirectly (same method, headers, params, and body), subject to browser CORS policy.
- Via server — the client
- The response is shown in the response editor (status, headers, and body).
Saved sessions persist the query string (and metadata such as save time) so selecting an entry restores the same request shape.
The /doc route reads the current request from the same encoded query parameters as the main page. It shows the HTTP method, URL, and tables for params, headers, and body. Each field lists a key, an inferred type (including JSON-aware parsing for body values), and an example value. Use the back control to return to the editor with the request state unchanged.
Fetcher ships a web app manifest and launcher icons under public/. Supported browsers can install it for a standalone window with the app theme color applied. The manifest is linked from the shared app layout alongside standard meta tags for description and Open Graph.
e2e/
tests/ Playwright specs (request flows, errors, saved sessions, key-value UI)
mocks/ Route mocks for stable tests
utils/ Test helpers
public/
manifest.webmanifest PWA manifest and install metadata
icons/ Launcher icons for installed clients
src/
components/ UI (request editor, panels, tabs, Monaco wrapper, saved sessions, doc actions)
constants/ Shared constants (e.g. `data-testid` keys for e2e)
domain/ HTTP and session types and helpers
hooks/ React hooks (clipboard, floating UI positioning)
layouts/ App shell (manifest link, theme color, viewport)
pages/ Index and documentation routes, API routes
store/ Nanostores for requests, responses, and saved sessions
styles/ Global CSS
utils/ Request documentation parsing and formatting
ISC — see package.json.