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.

try it live ↓
<ApiClient />
fig. 1 — the complete workspace, running live. send a request.
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.

  1. 01

    request builder

    All seven HTTP methods, params and headers tables, JSON, text, URL-encoded and multipart bodies, timeouts and redirects.

    GETPOSTPUTPATCHDELETEHEADOPTIONS
    fig. 2.1 — methods
  2. 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 kB
    prepare
    waiting
    download
    fig. 2.2 — timing
  3. 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
  4. 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
  5. 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
  6. 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 header
    fig. 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

src/App.tsx
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.

prepareGET {{baseUrl}}/users?page=2resolved
authbearer · {{apiToken}} → ••••••••masked
middlewareloggingnext()
transportfetch · timeout 10s200 OK · 142 ms
ApiErrorkind: http | network | timeout | aborted | parse | invalid-requesttyped
fig. 3 — sample run

[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.

  1. 01

    engine

    createApiClient()

    Middleware, custom transports, typed errors and timeouts. No UI and no React required.

    6.85 kB
  2. 02

    hooks

    useApiRequest()

    Loading, error and cancellation state for your own components, on the same engine.

    7.40 kB
  3. 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
  4. 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

fig. 4 — composed layout, running live

[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