Skip to content

envoiReturn T. Keep transport details out.

A framework-free HTTP response layer for axios, fetch, and ofetch. Configure business codes, hooks, and adapters once; expose Promise everywhere.

envoi's opened-envelope mark
Protocol workbench

From backend response todata or BizError

Choose a backend response, run the repository's real createHttp, and compare the raw response with the final resolved value or rejected BizError.

real envoi clientcreateHttp()
ScenarioEnvelope successUnwrap data
Real request pipelineHTTP 200 · OK
Backend responseOK
HTTP 200
{
  "status": 200,
  "body": {
    "code": 200,
    "msg": "ok",
    "data": {
      "id": 42,
      "name": "Ada"
    }
  }
}
envoi outcome
Ready to run
// Run the scenario to inspect its resolved value or BizError
Unwrap dataReady to run

One client, four explicit layers

ts
const instance = createAxiosInstance({ withCredentials: true });
const http = createHttp({
  adapter: axiosAdapter(instance),
  defaults: { baseURL: "/api", timeout: 15_000 },
  envelope: { code: "code", msg: "msg", data: "data" },
  hooks: { onRequest: auth(getToken), onResponseError: showError },
});

Request hooks prepare the call, the adapter executes HTTP, and the selected response policy produces Promise<T>. Application state stays with the caller.

Production paths, not isolated snippets

Use envoi when repetition has become behavior

A small project with two plain requests can keep native fetch or axios. envoi becomes useful when several endpoints or applications must agree on response extraction, business failures, shared headers, adapter behavior, and the value returned to callers.

End-to-end exampleBuild the client you would actually ship.
Open the example →

Released under the MIT License.