DEV Community

Cover image for Forge Query - A 3KB Alternative to React Query with Built-in DevTools
John Yaghobieh
John Yaghobieh

Posted on

Forge Query - A 3KB Alternative to React Query with Built-in DevTools

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));
}, []);
Enter fullscreen mode Exit fullscreen mode

...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
Enter fullscreen mode Exit fullscreen mode

Setup

import { QueryClient, QueryClientContext } from '@forgedevstack/forge-query';

const queryClient = new QueryClient();

function App() {
  return (
    <QueryClientContext.Provider value={queryClient}>
      <YourApp />
    </QueryClientContext.Provider>
  );
}
Enter fullscreen mode Exit fullscreen mode

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>
  );
}
Enter fullscreen mode Exit fullscreen mode

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>
  );
}
Enter fullscreen mode Exit fullscreen mode

DevTools

This is my favorite part. Add one component:

import { ForgeQueryDevTools } from '@forgedevstack/forge-query/devtools';

function App() {
  return (
    <>
      <YourApp />
      <ForgeQueryDevTools />
    </>
  );
}
Enter fullscreen mode Exit fullscreen mode

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:

  1. Smaller bundle - 3KB vs 13KB
  2. Built-in DevTools - No extra package to install
  3. 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

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)