mrkeyoor.com_
Sun 20 Sept 11:43 UTC
npmWeb Frontendupdated 20 Sept 2026

superagent review

SuperAgent is an HTTP client for Node and browsers built around a chainable request object. query, send, set, timeout, retry, field, attach, and use configure that object; awaiting it or calling end sends the request. The response exposes status, headers, text, and a parsed body, while HTTP failures reject by default. Our install showed an older distribution shape: CommonJS, no exports map, and no included TypeScript declarations. Version 10.3.0 refreshes dependencies and test tooling and restores a browser-side request.agent compatibility proxy.

Verdict

Keep SuperAgent where cookie agents, multipart helpers, plugins, or SuperTest make its old fluent API useful. For a new JSON client, fetch or a typed current wrapper costs less.

We installed it

Lab card: what happened when we installed superagentScreenshot of superagent documentation
Install✓ · 1.6s42 packages on disk · 6 MB
ImportESM import works · require() works · CommonJS package
Browser19.7 KBgzipped (62.6 KB minified), bundled with esbuild
Typesno TypeScript types found
Known vulns00 critical · 0 high · 0 moderate · 0 low (npm audit)

Answers from our run

Does superagent install cleanly?

Yes. In a fresh container with an empty cache, npm install superagent finished in 2 seconds, leaving 42 packages and 6 MB on disk. npm audit reported no known vulnerabilities.

How much does superagent add to a browser bundle?

19.7 KB gzipped (62.6 KB minified) when the whole package is bundled for the browser with esbuild. Importing only part of it is usually smaller.

Does superagent work with both ESM and CommonJS?

Yes. Both import 'superagent' and require('superagent') worked in Node 22 in our run. The package is published as CommonJS.

Does superagent include TypeScript types?

No type declarations were found in our install, so TypeScript users need their own declarations.

superagent or undici: which should you use?

undici: Use it for a modern Node HTTP stack and fetch-compatible APIs without browser support. Keep SuperAgent where cookie agents, multipart helpers, plugins, or SuperTest make its old fluent API useful.

When should you not use superagent?

A new application only sends ordinary JSON requests; built-in fetch avoids the 42-package and 6 MB install we measured

API stability5/5The get, post, query, send, set, field, attach, timeout, retry, agent, end, and promise paths have survived many major versions. The project says its breaks usually affect uncommon behavior or stricter error handling. Version 10.3.0 adds a compatibility object and dependency updates rather than replacing routine request chains, so established clients face little migration work at the public method level.
Docs3/5The hosted guide documents query strings, JSON and form bodies, multipart uploads, response parsing, error handling, timeouts, retries, agents, browser credentials, plugins, and upgrade notes with working chains. Finding one detail often means searching a long page, and the browser support table names old browser releases. There is no package-owned TypeScript guide because declarations are not shipped with SuperAgent itself.
Maintenance2/5Version 10.3.0 and the repository's latest push both occurred on 2026-01-06. Its release notes are mostly dependency, lockfile, test-runner, and compatibility work, with one browser request.agent proxy addition. GitHub search returned 179 open issues after pull requests were removed. This looks like upkeep for a mature dependency rather than a client receiving frequent new HTTP features.
Ecosystem4/5npm recorded 22,599,494 downloads during the latest week, and GitHub showed 16,642 stars. SuperTest makes the same request style familiar in Node API tests, and the project lists plugins for prefixing, caching, mocking, throttling, and timing. Some listed plugins are old, so each needs its own maintenance check. Missing bundled types also sends TypeScript users to a separately maintained DefinitelyTyped package.

Use it if

  • An existing SuperAgent or SuperTest codebase already depends on its request chains, response objects, and plugin convention
  • A Node client needs multipart fields and file attachments without assembling a form-data stream by hand
  • Several Node requests must reuse login cookies through one superagent.agent instance
  • One request needs opt-in retries plus separate response and total deadline timers
Skip it if

Setup reality

superagent 10.3.0 installed successfully in 1.6 seconds in our clean Node 22 container. node_modules held 42 packages using 6 MB. The package reports 9 direct dependencies, no peer dependencies, 588 KB unpacked, an MIT license, and a Node floor of 14.18.0. npm audit found 0 known vulnerabilities at all severities. It is CommonJS with no exports map; require() and ESM import both worked. No TypeScript declaration files were present.

Our browser-targeted build succeeded at 62.6 KB minified and 19.7 KB gzipped. Cross-origin browser cookies require withCredentials() on the request plus matching CORS headers from the server. Node cookie sessions use superagent.agent(). No project config file is required, and each request can be modified by a function passed to use(). That is a per-request hook, not a global response interceptor.

A request chain is lazy until it is awaited, piped, treated as a promise, or ended with end(). Pick one completion style. Calling end() and then() on the same object can send twice because the request is thenable rather than a plain native Promise. HTTP 4xx and 5xx failures usually include error.response, while DNS and connection failures do not. Timeouts are disabled until configured. A numeric timeout is an overall deadline; use an object to separate time to first response from total duration. Retries do not make a non-idempotent POST safe.

Patterns

Send query values and read JSON get-json-response

const superagent = require('superagent');

const response = await superagent
  .get('https://api.example.com/users')
  .query({ page: 2, active: true })
  .accept('json');

console.log(response.status, response.body);

Recognized response content types are parsed into body. The original response string is available as text.

Send an object as JSON post-json-body

const response = await superagent
  .post('https://api.example.com/orders')
  .set('Authorization', 'Bearer ' + token)
  .send({ sku: 'A-42', quantity: 2 });

console.log(response.body.id);

A plain object passed to send selects JSON. Later object calls overwrite duplicate properties from earlier calls.

Separate HTTP, timeout, and network errors classify-request-error

try {
  await superagent.get('https://api.example.com/orders/42');
} catch (error) {
  if (error.response) {
    console.error('HTTP', error.status, error.response.body);
  } else if (error.timeout) {
    console.error('timeout', error.code);
  } else {
    console.error('network', error.code);
  }
}

Rejected HTTP responses carry response. DNS and connection failures happen before a response exists.

Treat one 404 as an accepted result allow-expected-status

const response = await superagent
  .get('https://api.example.com/cache/maybe-missing')
  .ok((res) => res.status === 404 || res.status < 400);

const value = response.status === 404 ? null : response.body;

ok replaces the default status test. Keep it narrow so authorization failures and server errors continue to reject.

Limit first response and total duration set-two-timeouts

await superagent
  .get('https://api.example.com/export')
  .timeout({
    response: 5000,
    deadline: 30000,
  });

response covers the wait for initial data. deadline covers the whole request. Neither exists unless configured.

Retry a transient GET failure retry-idempotent-get

const response = await superagent
  .get('https://api.example.com/catalog')
  .timeout({ response: 3000, deadline: 10000 })
  .retry(2);

Retries apply only after you request them. Be cautious with POST when repeating the server action could duplicate work.

Combine form fields with a file upload-multipart-data

const response = await superagent
  .post('https://api.example.com/documents')
  .field('caption', 'signed agreement')
  .field('account', 'A-18')
  .attach('document', '/tmp/agreement.pdf');

Let SuperAgent set the multipart Content-Type and boundary. A manual header can leave the boundary missing.

Keep login cookies in Node reuse-cookie-session

const superagent = require('superagent');
const session = superagent.agent();

await session
  .post('https://example.com/login')
  .send({ email, password });

const account = await session.get('https://example.com/account');

The agent owns a cookie jar. Independent calls on the top-level export do not share that session.

Post a form-encoded token request send-urlencoded-form

const response = await superagent
  .post('https://auth.example.com/token')
  .type('form')
  .send({
    grant_type: 'client_credentials',
    scope: 'orders:read',
  });

type('form') chooses application/x-www-form-urlencoded. A plain object otherwise uses JSON.

Cancel using the request reference abort-inflight-request

const request = superagent.get('https://api.example.com/large-report');
const pending = request.then((res) => res.body);

setTimeout(() => request.abort(), 2000);

try {
  await pending;
} catch (error) {
  if (error.code !== 'ABORTED') throw error;
}

Cancellation is abort() on SuperAgent's request object. Retain that object until the operation finishes.

Configure one request with a plugin apply-request-defaults

function authenticated(request) {
  request.set('Authorization', 'Bearer ' + getToken());
  request.timeout({ response: 4000, deadline: 15000 });
}

const response = await superagent
  .get('https://api.example.com/profile')
  .use(authenticated);

use modifies this request. It does not install a response hook across every future request.

Pipe a response into a file stream-download-node

const fs = require('node:fs');

const request = superagent
  .get('https://downloads.example.com/archive.zip')
  .maxResponseSize(500 * 1024 * 1024);

request.pipe(fs.createWriteStream('/tmp/archive.zip'));

Piping avoids collecting the whole response in body. Do not also await this request or call end on it.

Alternatives

PackageRegistryPick it when
undicinpmUse it for a modern Node HTTP stack and fetch-compatible APIs without browser support.
axiosnpmUse it when bundled types and request or response interceptors fit the application's conventions.
gotnpmUse it for Node-only streaming, hooks, pagination, and detailed retry controls.

More web frontend guides

postcss · react · react-dom · tailwindcss · htmlparser2 · tailwind-merge · the whole shelf →

How this guide is made: grounded in the library's documentation, release notes, changelog, and issue history, on a fixed rubric — not a hands-on install of every release. The 50 most-downloaded entries are additionally install-verified in clean containers. Corrections: contact the desk.