More Examples
Vanilla / Node
Use chowbea-axios typed Axios clients in Node scripts, CLIs, and workers — no React required.
No components. No hooks. Just TypeScript, a generated client, and a Result you actually check.
Setup
Point [instance].env_accessor at process.env (the default) and set your base URL:
export API_BASE_URL="https://api.example.com"
bun run api:fetch # or npm run api:fetchCall an operation
import { api } from "../src/services/api/api.client";
import type { UserDto } from "../src/services/api/_generated/api.contracts";
async function main() {
const { data, error } = await api.op.listUsers({
params: { limit: 20 },
});
if (error) {
console.error(`[${error.code}] ${error.message}`);
process.exitCode = 1;
return;
}
for (const user of data as UserDto[]) {
console.log(user.id, user.email);
}
}
main();Adjust listUsers / UserDto to match your OpenAPI operationId and schemas. No operationId? That method won't exist — fix the spec.
Unwrap helper (optional)
If you prefer throw-on-error in scripts:
import type { ApiError, Result } from "../src/services/api/api.error";
export async function unwrap<T>(promise: Promise<Result<T>>): Promise<T> {
const { data, error } = await promise;
if (error) {
const err = new Error(error.message) as Error & { apiError: ApiError };
err.apiError = error;
throw err;
}
return data;
}
// usage
const user = await unwrap(api.op.getUser({ id: process.argv[2]! }));
console.log(user.email);Path-based still works
const { data, error } = await api.get("/users/{id}", { id: "123" });Prefer api.op when you have operation IDs — names beat path strings in a growing codebase.
Auth in Node
bearer-localstorage is a browser toy. In Node, use auth_mode = "custom" and attach a header in api.instance.ts:
axiosInstance.interceptors.request.use((config) => {
const token = process.env.API_TOKEN;
if (token) config.headers.Authorization = `Bearer ${token}`;
return config;
});