Forge Query: A 3KB Alternative to React Query
If you've ever written this pattern in React...
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
fetch('/api/users')
.then(res => res.json())
.then(setData)
.catch(setError)
.finally(() => setLoading(false));
}, []);
...you know the pain. No caching. No retries. Boilerplate everywhere.
Libraries like React Query solve this beautifully. But at 13KB, they can feel heavy for smaller projects.
That's why I built Forge Query.
What is it?
A lightweight data fetching library that gives you:
- Smart caching (LRU)
- Background refetching
- Automatic retries
- Request deduplication
- DevTools (in-app + Chrome)
- TypeScript support
- Bundle size: ~3KB
Quick Start
npm install @forgedevstack/forge-query
Setup
import { QueryClient, QueryClientContext } from '@forgedevstack/forge-query';
const queryClient = new QueryClient();
function App() {
return (
<QueryClientContext.Provider value={queryClient}>
<YourApp />
</QueryClientContext.Provider>
);
}
Fetch Data
import { useQuery } from '@forgedevstack/forge-query';
function Users() {
const { data, isLoading, error } = useQuery({
queryKey: ['users'],
queryFn: () => fetch('/api/users').then(r => r.json()),
});
if (isLoading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
return (
<ul>
{data.map(user => <li key={user.id}>{user.name}</li>)}
</ul>
);
}
Your data is now:
- Cached automatically
- Refetched when window regains focus
- Retried 3 times on failure
- Shared across all components using the same key
Mutations
import { useMutation, useQueryClient } from '@forgedevstack/forge-query';
function CreateUser() {
const queryClient = useQueryClient();
const { mutate, isLoading } = useMutation({
mutationFn: (user) => fetch('/api/users', {
method: 'POST',
body: JSON.stringify(user),
}),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['users'] });
},
});
return (
<button onClick={() => mutate({ name: 'John' })} disabled={isLoading}>
Create User
</button>
);
}
DevTools
This is my favorite part. Add one component:
import { ForgeQueryDevTools } from '@forgedevstack/forge-query/devtools';
function App() {
return (
<>
<YourApp />
<ForgeQueryDevTools />
</>
);
}
You get a floating panel showing:
- All queries with their status
- Cache hit/miss statistics
- Activity logs
- Actions to refetch/invalidate/remove queries
There's also a Chrome Extension for a dedicated DevTools tab!
Why I Built This
I'm a huge fan of React Query. But for smaller projects and landing pages, I wanted:
- Smaller bundle - 3KB vs 13KB
- Built-in DevTools - No extra package to install
- Simpler API - Fewer concepts to learn
Comparison
| Feature | Forge Query | React Query | SWR |
|---|---|---|---|
| Bundle | ~3KB | ~13KB | ~4KB |
| DevTools | Built-in | Separate | No |
| TypeScript | First-class | First-class | First-class |
| Cache Control | Full | Full | Limited |
Resources
- npm: @forgedevstack/forge-query
- Docs: forgedevstack.com/query
- GitHub: github.com/forgedevstack/forge-query
What's Next?
- useInfiniteQuery for pagination
- Safari DevTools extension
- Offline persistence
- React Native support
Forge Query is part of the ForgeStack ecosystem - a collection of developer tools for React and Node.js. Check out forgedevstack.com for more!
If you try it out, I'd love to hear your feedback. Drop a comment below or open an issue on GitHub!
Top comments (0)