Skip to content

Configuration Reference

createClient vs HttpClientFactory

Both APIs create and cache HttpClient instances. Choose based on your needs:

createClientHttpClientFactory.create
API styleSingle options objectThree positional arguments
Preset supportpreset: 'resilient-api'
ErgonomicsFlat config, easy to readExplicit separation of concerns
Shared cache✅ same cache✅ same cache
Recommended forNew projects, preset usersAdvanced use, explicit control
typescript
import { createClient } from 'super-http'

const api = createClient({
  baseURL: 'https://api.example.com',
  preset: 'resilient-api',            // preset applies circuit breaker + retry + bulkhead
  headers: { 'X-Service': 'checkout' },
  pool: { maxSockets: 150 },          // override one pool setting
})
typescript
import { HttpClientFactory } from 'super-http'

const api = HttpClientFactory.create(
  'https://api.example.com',
  { headers: { 'X-Service': 'checkout' } },   // http config
  { maxSockets: 150, timeout: 15_000 },         // pool config
)

// add resilience manually
api
  .circuitBreak({ failureThreshold: 10, successThreshold: 3, timeoutMs: 10_000 })
  .retry(3, new ExponentialJitterRetryStrategy(100, 10_000))
  .bulkhead({ maxConcurrent: 50, maxQueue: 200 })

Both share the same cache. The following two calls return the same instance:

typescript
const a = createClient({ baseURL: 'https://api.example.com' })
const b = HttpClientFactory.create('https://api.example.com')
console.log(a === b) // true

PoolConfig

Passed as pool in createClient, or as the third argument in HttpClientFactory.create.

OptionTypeDefaultDescription
maxSocketsnumber50Max concurrent sockets per host
maxFreeSocketsnumber10Max idle keep-alive sockets
keepAlivebooleantrueEnable TCP keep-alive
keepAliveMsecsnumber1000Keep-alive probe interval (ms)
timeoutnumber30000Request timeout (ms)
typescript
createClient('https://api.example.com', {}, {
  maxSockets: 100,
  maxFreeSockets: 20,
  keepAlive: true,
  keepAliveMsecs: 2_000,
  timeout: 15_000,
})

.retry(retries, strategy, retryOn?)

ParameterTypeDescription
retriesnumberMax retry attempts
strategyRetryStrategy | numberDelay strategy or fixed ms
retryOnnumber[]Optional: retry only on these HTTP status codes

Strategies:

ClassDelay pattern
FixedRetryStrategy(ms)Constant
ExponentialRetryStrategy(init, max, factor?)Doubles each attempt
ExponentialJitterRetryStrategy(init, max, factor?)Random in [0, cap] — recommended
RetryAfterStrategy(init?, max?, factor?)From Retry-After header, jitter fallback

.circuitBreak(config)

OptionTypeDescription
failureThresholdnumberFailures before circuit opens
successThresholdnumberSuccesses to close from half-open
timeoutMsnumberOpen duration before probing (ms)

.bulkhead(config)

OptionTypeDefaultDescription
maxConcurrentnumberMax in-flight requests
maxQueuenumber50Max queued requests
queueTimeoutMsnumberundefinedReject queued after this ms

.rateLimit(config)

OptionTypeDefaultDescription
permitLimitnumberMax requests per window
windowMsnumberWindow size in ms
queueRequestsbooleanfalseQueue excess instead of rejecting
queueTimeoutMsnumberundefinedMax wait time for queued token

.fallback(fn)

typescript
client.fallback((error: unknown) => fallbackValue)
client.fallback(async (error: unknown) => await alternativeSource())

.dedup()

No configuration — enables request deduplication (idempotent calls only).


.use(plugin)

typescript
import { LoggerPlugin, MetricsReporterPlugin } from 'super-http'

client.use(LoggerPlugin({ prefix: '[my-service]', level: 'info' }))
client.use(MetricsReporterPlugin({ intervalMs: 60_000 }))

Per-request policy

Any resilience setting can be overridden for a single request via policy:

typescript
// Disable retry for a payment (non-idempotent)
await api.post('/charges', payload, {
  policy: { retry: false, timeout: 10_000 },
})

// Silent fallback for non-critical endpoint
await api.get('/recommendations', {
  policy: { timeout: 300, fallback: () => [] },
})

// Stricter circuit breaker on one endpoint
await api.get('/inventory', {
  policy: {
    circuitBreaker: { failureThreshold: 2, successThreshold: 1, timeoutMs: 3_000 },
  },
})
policy fieldTypeDescription
timeoutnumberOverride timeout for this request (ms)
retry{ attempts, delayMs?, retryOn? } | falseOverride retry, or false to disable
circuitBreakerPartial<CircuitBreakerConfig> | falseOverride CB config, or false to bypass
fallback(error) => TOverride fallback for this request

.on(events)

HookEvent typeFired when
onRequestAxiosRequestConfigBefore each HTTP request
onResponseAxiosResponseOn successful response
onErrorunknownOn final failure
onRetryRetryEventBefore each retry attempt
onCircuitStateChangeCircuitStateChangeEventOn circuit state transition
onBulkheadRejectBulkheadRejectEventBulkhead queue full
onFallbackFallbackEventFallback handler invoked
onRateLimitRejectRateLimitRejectEventRate limit token unavailable

.metrics() / .resetMetrics()

typescript
const m = client.metrics()
// { requests, success, failed, retries, circuitBreakerTrips,
//   bulkheadRejects, rateLimitRejects, fallbacks,
//   avgLatency, p50Latency, p95Latency, p99Latency, uptime }

client.resetMetrics() // clear all counters

HttpClientFactory.clear()

Clears all cached singleton instances (shared between createClient and HttpClientFactory.create).

typescript
import { HttpClientFactory } from 'super-http'

afterEach(() => HttpClientFactory.clear()) // tests

HTTP methods

MethodSignature
getget<T>(url, config?)
postpost<T>(url, data?, config?)
putput<T>(url, data?, config?)
patchpatch<T>(url, data?, config?)
deletedelete<T>(url, config?)
requestrequest<T>(axiosConfig)

Released under the MIT License.