Migrating from Axios
super-http is a superset of Axios — every Axios feature works, and you add resilience on top. Migration is a drop-in replacement in most cases.
Basic migration
typescript
import axios from 'axios'
const res = await axios.get('https://api.example.com/users')typescript
import { createClient } from 'super-http'
const http = createClient({ baseURL: 'https://api.example.com' })
const res = await http.get('/users')axios.create → createClient
typescript
const api = axios.create({
baseURL: 'https://api.example.com',
timeout: 5000,
headers: { Authorization: `Bearer ${token}` },
})typescript
import { createClient } from 'super-http'
const api = createClient({
baseURL: 'https://api.example.com',
timeout: 5000,
headers: { Authorization: `Bearer ${token}` },
// optional: add a preset for instant resilience
preset: 'resilient-api',
})Interceptors → Lifecycle hooks
typescript
api.interceptors.request.use((config) => {
config.headers['X-Request-ID'] = uuid()
return config
})
api.interceptors.response.use(
(res) => { logger.info(`← ${res.status}`) ; return res },
(err) => { logger.error('request failed', err) ; return Promise.reject(err) },
)typescript
api.on({
onRequest: (config) => { config.headers!['X-Request-ID'] = uuid() },
onResponse: (response) => logger.info(`← ${response.status}`),
onError: (error) => logger.error('request failed', error),
})TIP
Lifecycle hooks (onRequest, onResponse, onError) can also modify request config — return value is not needed, mutations are picked up automatically.
Manual retry → .retry()
typescript
async function fetchWithRetry(url: string, retries = 3) {
for (let i = 0; i < retries; i++) {
try {
return await axios.get(url)
} catch (e) {
if (i === retries - 1) throw e
await sleep(500)
}
}
}typescript
import { createClient, ExponentialJitterRetryStrategy } from 'super-http'
const api = createClient({ baseURL: 'https://api.example.com' })
api.retry(3, new ExponentialJitterRetryStrategy(100, 5_000))
// That's it — retries happen automatically
const res = await api.get('/data')Manual timeout → PoolConfig
typescript
const res = await axios.get(url, { timeout: 5000 })typescript
const api = createClient({
baseURL: 'https://api.example.com',
pool: { timeout: 5000 },
})typescript
const res = await api.get('/slow-endpoint', { policy: { timeout: 30_000 } })Cancel tokens → AbortSignal
Axios cancel tokens are supported transparently. You can also use the standard AbortSignal:
typescript
const controller = new AbortController()
setTimeout(() => controller.abort(), 5000)
await api.get('/data', { signal: controller.signal })Headers, params, auth — no changes
All Axios request config options work unchanged:
typescript
await api.post('/users', payload, {
params: { locale: 'pt-BR' },
headers: { 'X-Idempotency-Key': uuid() },
auth: { username: 'user', password: 'pass' },
})Upload / download progress
typescript
await api.post('/upload', formData, {
onUploadProgress: (e) => console.log(`${Math.round(e.progress! * 100)}%`),
})
await api.get('/file', {
responseType: 'stream',
onDownloadProgress: (e) => console.log(`${Math.round(e.progress! * 100)}%`),
})Migration checklist
- [ ] Replace
axios.create({ baseURL, ... })withcreateClient({ baseURL, ... }) - [ ] Replace
axios.interceptors.request.usewithclient.on({ onRequest }) - [ ] Replace
axios.interceptors.response.usewithclient.on({ onResponse, onError }) - [ ] Replace manual retry loops with
client.retry(n, strategy) - [ ] Add a preset (optional but recommended):
preset: 'resilient-api' - [ ] Replace
import axios from 'axios'withimport { createClient } from 'super-http'