Xior
A liteweight fetch wrapper with plugins support and similar API to axios.
Install / Use
/learn @suhaotian/XiorREADME
Intro
A Lightweight HTTP request library based on fetch with plugin support and similar API to axios.
Features:
- 🔥 Use fetch
- 🫡 Similar axios API:
axios.create/axios.interceptors/.get/post/put/patch/delete/head/options - 🤙 Supports timeout, canceling requests, and nested query encoding
- 🥷 Supports plugins: error retry, deduplication, throttling, cache, error cache, mock, and custom plugins
- 🚀 Lightweight (~6KB, Gzip ~3kb)
- 👊 Unit tested and strongly typed 💪
Table of Contents
- Intro
- Table of Contents
- Getting Started
- Installing
- Create instance
- GET / POST / DELETE / PUT / PATCH / OPTIONS / HEAD
- Change default headers or params
- Get response headers
- Upload file
- Using interceptors
- Cleanup interceptors
- Timeout and Cancel request
- Proxy or use custom fetch implementations
- Custom data parser
- Encrypt and Decrypt Example
- Tips: Make your SSR(Server-side Rendering) app more stable and faster
- Plugins
- Helper functions
- FAQ
- 1. Is xior 100% compatible with
axios? - 2. Can I use xior in projects like Bun, Expo, React Native, RemixJS, Next.js, Vue, Nuxt.js, Tauri or
NervJS/Taro? - 3. How can I use custom fetch implementation or How to support proxy feature?
- 4. How do I handle responses with types like
'stream','document','arraybuffer', or'blob'? - 5. How do I change default throw error behaviour,
validStatusorvalidResponse? - 6. How do I support older browsers?
- 7. Why is xior named "xior"?
- 8. Where can I ask additional questions?
- 1. Is xior 100% compatible with
- Migrate from axios to xior
- Migrate from
fetchto xior - API Reference
- Star History
- Thanks
Getting Started
Installing
Package manager
# npm
npm install xior
# pnpm
pnpm add xior
# bun
bun add xior
# yarn
yarn add xior
Use CDN
Since v0.2.1, xior supports UMD format
Use jsDelivr CDN:
<script src="https://cdn.jsdelivr.net/npm/xior@0.8.3/dist/xior.umd.js"></script>
<!-- Usage -->
<script>
console.log(xior.VERSION);
xior.get('https://exmapledomain.com/api').then((res) => {
console.log(res.data);
});
</script>
Use unpkg CDN:
<script src="https://unpkg.com/xior@0.8.3/dist/xior.umd.js"></script>
<!-- Usage -->
<script>
xior.get('https://exmapledomain.com/api').then((res) => {
console.log(res.data);
});
</script>
Create instance
import xior from 'xior';
export const xiorInstance = xior.create({
baseURL: 'https://apiexampledomain.com/api',
headers: {
// put your common custom headers here
},
});
GET / POST / DELETE / PUT / PATCH / OPTIONS / HEAD
GET
HEAD/DELETE/OPTIONSare same usage asGETmethod
async function run() {
const { data } = await xiorInstance.get('/');
// with params and support nested params
const { data: data2 } = await xiorInstance.get('/', { params: { a: 1, b: 2, c: { d: 1 } } });
// with headers
const { data: data3 } = await xiorInstance.get('/', {
params: { a: 1, b: 2 },
headers: {
'content-type': 'application/x-www-form-urlencoded',
},
});
// types
const { data: data4 } = await xiorInstance.get<{ field1: string; field2: number }>('/');
}
POST
PUT/PATCHmethods are same usage asPOST
async function run() {
const { data: data3 } = await xiorInstance.post<{ field1: string; field2: number }>(
'/',
{ a: 1, b: '2' },
{
params: { id: 1 },
headers: {},
}
);
}
Change default headers or params
import xior from 'xior';
export const xiorInstance = xior.create({
baseURL: 'https://apiexampledomain.com/api',
});
function setAccessToken(token: string) {
// xiorInstance.defaults.params['x'] = 1;
xiorInstance.defaults.headers['Authorization'] = `Bearer ${token}`;
}
function removeUserToken() {
// delete xiorInstance.defaults.params['x'];
delete xiorInstance.defaults.headers['Authorization'];
}
Get response headers
import xior from 'xior';
const xiorInstance = xior.create({
baseURL: 'https://apiexampledomain.com/api',
});
const { data, headers } = await xiorInstance.get('/');
console.log(headers.get('X-Header-Name'));
Upload file
xior supports file uploads using the FormData API and provides an optional 'xior/plugins/progress' plugin for simulating upload progress, usage similar to Axios.
import Xior from 'xior';
import uploadDownloadProgressPlugin from 'xior/plugins/progress';
const http = Xior.create({});
http.plugins.use(
uploadDownloadProgressPlugin({
progressDuration: 5 * 1000,
})
);
const formData = new FormData();
formData.append('file', fileObject);
formData.append('field1', 'val1');
formData.append('field2', 'val2');
http.post('/upload', formData, {
onUploadProgress(e) {
console.log(`Upload progress: ${e.progress}%`);
},
// progressDuration: 10 * 1000
});
Using interceptors
xior supports interceptors similar to Axios, allowing you to modify requests and handle responses programmatically.
Request interceptors:
import xior, { merge } from 'xior';
const http = xior.create({
// ...options
});
http.interceptors.request.use((config) => {
const token = localStorage.getItem('REQUEST_TOKEN');
if (!token) return config;
return merge(config, {
headers: {
Authorization: `Bearer ${token}`,
},
});
});
// One more interceptors for request
http.interceptors.request.use((config) => {
return config;
});
async function getData() {
const { data } = await http.get('/');
console.log(data);
return data;
}
Response interceptors:
import xior, { merge } from 'xior';
const http = xior.create({});
http.interceptors.response.use(
(result) => {
const { data, request: config, response: originalResponse } = result;
return result;
},
async (error) => {
if (error instanceof TypeError) {
console.log(`Request error:`, error);
}
if (error?.response?.status === 401) {
localStorage.removeItem('REQUEST_TOKEN');
}
return Promise.reject(error);
}
);
async function getData() {
const { data } = await http.get('/');
console.log(data);
return data;
}
Cleanup interceptors
import xior from 'xior';
const http = xior.create({});
// Cleanup request interceptors
const handler1 = http.interceptors.request.use((config) => {
return config;
