open source · MIT · react 18 & 19 · v0.1.0
The API testing workspace, inside your React app.
drop a Postman-style workspace into internal tools, developer portals, admin panels and docs. or use the panels, hooks and typed engine to build your own.
- http methods
- 7
- complete workspace
- 50.11 kB gzip
- engine only
- 6.85 kB gzip
- runtime dependencies
- 0 besides React
built for
- React 18
- React 19
- Next.js App Router
- Vite
- Node 18+
- ESM + CJS
- TypeScript
[F] features
Everything a request needs. Nothing it doesn't.
Request builder, response inspector, auth, environments, collections, history and cURL, in one component.
- 01
request builder
All seven HTTP methods, params and headers tables, JSON, text, URL-encoded and multipart bodies, timeouts and redirects.
GETPOSTPUTPATCHDELETEHEADfig. 2.1 — methods - 02
response inspector
Status, time, size and a timing breakdown. Pretty JSON, a collapsible tree, raw text, sanitized previews and search.
200 OK142 ms1.2 kBfig. 2.2 — timing - 03
auth
Bearer, Basic, API key, an OAuth 2.0 integration point, custom headers and reusable auth profiles.
- bearer Authorization: Bearer <token>
- basic Authorization: Basic <base64>
- apiKey header or query
- profile reusable credentials
fig. 2.3 — auth types - 04
environments
Write {{variables}} in URLs, params, headers, bodies and auth, with scoped precedence and secret masking.
{{baseUrl}}/users/{{userId}}→ https://api.example.com/users/1{{apiToken}} ••••••••fig. 2.4 — resolve - 05
collections & history
Folders, drag and drop, OpenAPI 3 / Swagger 2 import, a documented JSON export and replayable history.
- ▾ JSONPlaceholder
- ▾ Posts
- GET List posts
- POST Create post
- GET User by id
fig. 2.5 — tree - 06
curl in, curl out
Copy any request as cURL, or paste a cURL command into the URL bar to import it.
$ curl https://api.example.com/users \-H 'Accept: application/json'→ GET /users · 1 headerfig. 2.6 — import
[C] quick start
Your API workspace, defined in code.
Import the component and the stylesheet. Every style is scoped under .m2a, so nothing leaks into the rest of your page.
▾ your-app
import { ApiClient } from 'm2api-client'; import 'm2api-client/styles.css'; export default function App() { return ( <div style={{ height: '100vh' }}> <ApiClient baseUrl="https://api.example.com" theme="light" initialMethod="GET" /> </div> ); }
[E] engine
One engine. No UI required.
createApiClient() is the engine behind everything. It runs in browsers, Node 18+, workers and tests, with middleware, custom transports, typed errors and timeouts.
[L] architecture
Open at every layer.
Use the whole workspace, compose the panels, or call the hooks and engine from your own UI. Sizes are minified and gzipped with React external.
- 01
engine
createApiClient()Middleware, custom transports, typed errors and timeouts. No UI and no React required.
6.85 kB - 02
hooks
useApiRequest()Loading, error and cancellation state for your own components, on the same engine.
7.40 kB - 03
panels
<RequestBuilder /> <ResponseViewer />Compose your own layout from panels that share one workspace store, or control them yourself.
22.74 kB + 10.19 kB - 04
workspace
<ApiClient />The complete Postman-style workspace: sidebar, tabs, environments, history and import/export.
50.11 kB
ApiClientProvider holds one workspace store; CollectionExplorer, RequestBuilder, ResponseViewer and EnvironmentSelector connect to it. source: examples/composed-layout.tsx
[K] accessibility
Built for the keyboard.
All controls have accessible names, focus is visible everywhere, dialogs trap and restore focus, and status changes are announced to screen readers.
- ⌘/CtrlEnterSend request
- ⌘/CtrlSSave request
- ⌘/CtrlShiftFFormat the JSON body
- EscCancel the running request
- ←→HomeEndMove between tabs
- EnterF2DelOpen, rename and delete in the collection tree
- EnterShift + EnterNext / previous search match
- EscTabLeave a code editor (Tab indents)
[P] m2toolkit
More open-source packages from M2Toolkit.
[Q] faq
Questions, answered.
Does it get around CORS?
No. Frontend code cannot bypass CORS, and this library does not try to. A cross-origin request only succeeds when the server allows your page's origin. When it doesn't, the workspace shows a network error with the likely causes. Use a small server-side proxy for APIs you don't control.
Can I use it with Next.js?
Yes. All components are marked 'use client', so you can render them from a Server Component page. Import m2api-client/styles.css once in your root layout.
Where is my data stored?
Nothing is stored by default. Opt in with the persistence option: local or session storage, memory, or your own adapter (IndexedDB, an encrypted store or a backend). Secret values and literal credentials are not stored unless you opt in.
Should I put API keys in it?
Never embed OAuth client secrets, API keys for privileged accounts, or production credentials in frontend code. Use short-lived tokens from your backend, or a proxy that adds credentials. Literal credentials are masked in history, snapshots and errors.
Can I use the engine without React?
Yes. createApiClient() has no UI and no React dependency, so it runs in browsers, Node 18+, workers and tests.
What isn’t supported yet?
Pre-request and test scripts (deliberately absent), GraphQL schema introspection, WebSockets and server-sent events, Postman collection import, request chaining and response diffing.
Start testing APIs where your users already are.
>_ npm install m2api-client