Package Exports
- react-api-weaver
Readme
โก React API Weaver
Convert OpenAPI/Swagger YAML specifications into typed React hooks with caching, polling, and cancellation support.
๐ Features
- ๐ OpenAPI/Swagger Support: Convert YAML specs into TypeScript/JavaScript code
- ๐ฃ React Hooks: Method-specific hooks (
useGet,usePost,usePut,usePatch,useDelete) - ๐พ Smart Caching: Built-in response caching with TTL support
- ๐ Polling: Auto-refresh data at regular intervals
- ๐ Request Cancellation: Abort in-flight requests
- ๐ Full TypeScript Support: Auto-generated types from OpenAPI schemas
- ๐ Zero Configuration: Works out of the box
- ๐ฏ Type-Safe: End-to-end type safety from API to UI
- โก Lightweight: Minimal dependencies, tree-shakeable
๐ฆ Installation
npm install react-api-weaver๐ Quick Start
1. Create an OpenAPI YAML file
Create a api.yaml file with your API specification:
openapi: 3.0.0
info:
title: My API
version: 1.0.0
servers:
- url: https://api.example.com
paths:
/users:
get:
operationId: getUsers
responses:
'200':
description: Success
content:
application/json:
schema:
type: array
items:
type: object
properties:
id:
type: integer
name:
type: string2. Generate API client code
npx react-api-weaver generate -i api.yaml -o src/generatedThis generates TypeScript functions and types:
src/generated/api.ts- API functionssrc/generated/types.ts- TypeScript types/interfaces for requests and responsessrc/generated/index.ts- Exports for easy importing
3. Use the generated hooks in your React components
import React from 'react';
import { useGet } from 'react-api-weaver';
import { getUsers } from './generated/api';
function UserList() {
const { data, loading, error, refetch, abort } = useGet(
() => getUsers(),
{
cache: true,
polling: 30000, // Refresh every 30 seconds
}
);
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
return (
<div>
<button onClick={refetch}>Refresh</button>
<button onClick={abort}>Cancel</button>
{data?.map(user => (
<div key={user.id}>{user.name}</div>
))}
</div>
);
}๐ CLI Usage
Generate Command
Generate API client code from OpenAPI YAML:
react-api-weaver generate -i <input.yaml> -o <output-dir> [options]Options:
-i, --input <path>: Path to OpenAPI YAML file (required)-o, --output <path>: Output directory for generated code (required)-f, --format <format>: Output format:ts,js, orboth(default:ts)-b, --base-url <url>: Base URL for API requests
Example:
react-api-weaver generate -i api.yaml -o src/generated -f ts -b https://api.example.comWatch Command
Watch for changes and regenerate automatically:
react-api-weaver watch -i <input.yaml> -o <output-dir> [options]Example:
react-api-weaver watch -i api.yaml -o src/generated๐ฃ Hooks API
useGet
Hook for GET requests with caching support.
const { data, loading, error, refetch, abort } = useGet(
apiFunction,
options
);usePost
Hook for POST requests (cache disabled by default).
const { data, loading, error, refetch, abort } = usePost(
apiFunction,
options
);usePut
Hook for PUT requests (cache disabled by default).
const { data, loading, error, refetch, abort } = usePut(
apiFunction,
options
);usePatch
Hook for PATCH requests (cache disabled by default).
const { data, loading, error, refetch, abort } = usePatch(
apiFunction,
options
);useDelete
Hook for DELETE requests (cache disabled by default).
const { data, loading, error, refetch, abort } = useDelete(
apiFunction,
options
);โ๏ธ Hook Options
All hooks accept an options object:
interface UseApiOptions<TData> {
// Enable/disable caching (default: true for GET, false for others)
cache?: boolean | {
ttl?: number; // Time to live in milliseconds
key?: string; // Custom cache key
};
// Polling interval in milliseconds
polling?: number;
// Whether the request should be executed (default: true)
enabled?: boolean;
// Success callback
onSuccess?: (data: TData) => void;
// Error callback
onError?: (error: Error) => void;
// Number of retries or boolean (default: 0)
retry?: number | boolean;
// Delay between retries in milliseconds (default: 1000)
retryDelay?: number;
}๐ฏ Return Values
All hooks return an object with:
interface UseApiResult<TData> {
// Response data
data: TData | null;
// Loading state
loading: boolean;
// Error object
error: Error | null;
// Manual refetch function
refetch: () => Promise<void>;
// Abort current request
abort: () => void;
}๐ก Examples
Example 1: Basic GET with Caching
import { useGet } from 'react-api-weaver';
import { getTodos } from './generated/api';
function TodoList() {
const { data, loading } = useGet(
() => getTodos({ _limit: 10 }),
{ cache: { ttl: 300000 } } // Cache for 5 minutes
);
if (loading) return <div>Loading...</div>;
return (
<ul>
{data?.map(todo => <li key={todo.id}>{todo.title}</li>)}
</ul>
);
}Example 2: POST with Success Callback
import { usePost } from 'react-api-weaver';
import { createTodo } from './generated/api';
function CreateTodo() {
const [title, setTitle] = useState('');
const { loading, refetch } = usePost(
() => createTodo({}, { title, userId: 1, completed: false }),
{
enabled: false,
onSuccess: (data) => {
console.log('Todo created:', data);
setTitle('');
},
}
);
const handleSubmit = (e) => {
e.preventDefault();
refetch();
};
return (
<form onSubmit={handleSubmit}>
<input
value={title}
onChange={(e) => setTitle(e.target.value)}
/>
<button disabled={loading}>Create</button>
</form>
);
}Example 3: Polling
import { useGet } from 'react-api-weaver';
import { getTodoById } from './generated/api';
function LiveTodo({ id }) {
const { data } = useGet(
() => getTodoById({ id }),
{ polling: 5000 } // Poll every 5 seconds
);
return <div>{data?.title}</div>;
}Example 4: Request Cancellation
import { useGet } from 'react-api-weaver';
import { getUsers } from './generated/api';
function UserList() {
const { data, loading, abort } = useGet(() => getUsers());
return (
<div>
{loading && <button onClick={abort}>Cancel</button>}
{data && <div>{data.length} users loaded</div>}
</div>
);
}Example 5: Conditional Requests
import { useGet } from 'react-api-weaver';
import { getUserById } from './generated/api';
function UserProfile({ userId }) {
const { data } = useGet(
() => getUserById({ id: userId }),
{ enabled: !!userId } // Only fetch when userId is available
);
return <div>{data?.name}</div>;
}๐ง Configuration
Custom Request Configuration
The generated API functions accept a RequestConfig parameter:
interface RequestConfig {
headers?: Record<string, string>;
baseURL?: string;
timeout?: number;
signal?: AbortSignal;
}Example:
const { data } = useGet(
() => getUsers({}, {
headers: { 'Authorization': 'Bearer token' },
timeout: 5000,
})
);Setting Default Base URL
You can set a base URL in three ways:
- In the OpenAPI YAML (servers section)
- Via CLI:
react-api-weaver generate -i api.yaml -o src/generated -b https://api.example.com - At runtime: Pass
baseURLin the request config
๐ Project Structure
your-project/
โโโ src/
โ โโโ generated/ # Generated API code
โ โ โโโ api.ts # Generated API functions
โ โ โโโ types.ts # TypeScript types/interfaces
โ โ โโโ index.ts # Exports (functions + types)
โ โโโ components/
โ โโโ UserList.tsx # Your components using hooks
โโโ api.yaml # OpenAPI specification
โโโ package.json๐ Type Exports
All TypeScript types are exported from the generated types.ts file. You can import types separately from functions:
// Import functions
import { getUsers, createUser } from './generated/api';
// Import types separately
import type { GetUsersResponse, CreateUserBody, CreateUserResponse } from './generated/types';
// Or import everything from index
import { getUsers, type GetUsersResponse } from './generated';Available Types:
{OperationName}Params- Request parameters (for GET, DELETE, etc.){OperationName}Body- Request body (for POST, PUT, PATCH){OperationName}Response- Response data type
Example:
import { getTodoById } from './generated/api';
import type { GetTodoByIdParams, GetTodoByIdResponse } from './generated/types';
function TodoComponent({ todoId }: { todoId: number }) {
const params: GetTodoByIdParams = { id: todoId };
const { data } = useGet<GetTodoByIdResponse>(
() => getTodoById(params)
);
return <div>{data?.title}</div>;
}๐ ๏ธ Development Workflow
Option 1: Manual Generation
{
"scripts": {
"generate": "react-api-weaver generate -i api.yaml -o src/generated"
}
}Run npm run generate when you update your API spec.
Option 2: Pre-development Generation
{
"scripts": {
"predev": "react-api-weaver generate -i api.yaml -o src/generated",
"dev": "vite"
}
}Automatically generates code before starting the dev server.
Option 3: Watch Mode (Separate Terminal)
react-api-weaver watch -i api.yaml -o src/generatedAutomatically regenerates code when the YAML file changes.
๐งช Testing with npm link
For local development and testing:
# In react-api-weaver directory
npm run build
npm link
# In your project directory
npm link react-api-weaver๐ค Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
๐ License
MIT
๐ Acknowledgments
- Built with TypeScript
- Powered by React
- OpenAPI parsing by Swagger Parser
- Bundled with tsdown
โ Support
If you find this project helpful, consider supporting me by buying me a coffee!
๐ Next Steps (Optional Enhancements)
Potential Future Features
- Automated testing (Jest + React Testing Library)
- React Query integration
- Middleware support (interceptors)
- Retry logic configuration
- Optimistic updates helper
- WebSocket support
- GraphQL support
- Zod schema validation
- SWR-style mutations
- Devtools integration
Documentation Improvements
- Video tutorial
- Interactive playground
- More examples (auth, pagination, etc.)
- API reference site
- Migration guides
Made with โค๏ธ by the React API Weaver team