Axios wrapper that handles cookies, proxies, and rate limiting so you don't have to.
Built this because I got tired of wiring up tough-cookie + proxy agents + request throttling every time I needed an HTTP client that behaves more like a browser session. It manages a cookie jar internally, follows redirects while preserving cookies across them, and optionally limits concurrent requests with a semaphore.
npm install @lounya/louxios axiosaxios is a peer dependency, bring your own version (^1.0.0).
import Louxios from '@lounya/louxios'
const client = new Louxios()
const result = await client.get('https://example.com/api/data')
if (result.isErr()) {
console.error(result.error.toString())
}
else {
console.log(result.value.data)
}Cookies are stored and sent automatically on subsequent requests, no setup needed.
Requests never throw. Every method returns a Result<AxiosResponse, LouxiosError> from neverthrow, so you always handle errors explicitly:
const result = await client.post('https://example.com/login', {
data: { user: 'me', pass: 'secret' },
})
if (result.isErr()) {
// result.error is a LouxiosError with stack trace and cause
return
}
// result.value is a normal AxiosResponse
const { data, status, headers } = result.valueTwo error cases are distinguished via ELouxiosError:
FatalRequestError- network failure, timeout, DNS resolution, etc.WrongStatusCodeReceived- the request completed but the status code didn't pass validation (2xx by default)
Pass a proxy URL string or pre-built agents:
// HTTP/HTTPS proxy
const client = new Louxios({
proxy: 'http://user:pass@proxy.example.com:8080',
})
// SOCKS proxy
const client = new Louxios({
proxy: 'socks5://proxy.example.com:1080',
})Supported protocols: http, https, socks, socks4, socks5.
You can also swap proxies at runtime:
const result = client.setProxy('http://new-proxy:8080')
if (result.isErr()) {
// invalid proxy URL
}Use the semaphore to limit concurrent requests and add delays between them:
const client = new Louxios({
useSemaphore: true,
simultaneousRequests: 3, // max 3 concurrent requests
timeoutBetweenRequests: 500, // 500ms cooldown per slot after each request
})Useful when you're hitting APIs with rate limits and don't want to deal with 429s manually.
Redirects are followed automatically (up to 10 by default) with proper cookie handling at each hop. The client correctly downgrades POST/PUT/PATCH to GET on 301/302/303 responses, matching browser behavior.
// override redirect limit globally
const client = new Louxios({ maxRedirects: 5 })
// or per-request
await client.get('https://example.com', { maxRedirects: 0 })By default, only 2xx responses are considered successful. You can customize this:
const client = new Louxios({
validateStatus: status => status < 500, // treat 4xx as success too
})Per-request override works too, just pass validateStatus in the request config.
The constructor accepts all axios config options (except withCredentials and the built-in proxy, which are managed internally), plus:
| Option | Type | Description |
|---|---|---|
proxy |
string | TProxyAgents |
Proxy URL or custom agents |
useSemaphore |
boolean |
Enable request throttling |
simultaneousRequests |
number |
Max concurrent requests (required if semaphore enabled) |
timeoutBetweenRequests |
number |
Delay in ms after each request per slot (required if semaphore enabled) |
maxRedirects |
number |
Max redirect hops (default: 10) |
validateStatus |
(status: number) => boolean |
Custom status validation |
Creates a new client instance with its own cookie jar.
Convenience methods. Return Promise<Result<AxiosResponse<T>, LouxiosError>>.
Low-level method, takes a full AxiosRequestConfig.
Set or change proxy at runtime. Returns Result<null, ErrorBase>.
Get the current HTTP or HTTPS agent. Returns the agent or undefined.
MIT