npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

react-smart-query

v1.0.1

Published

Offline-first, normalized, cache-versioned data layer for React Native and Expo. Built on TanStack Query with MMKV (native) and IndexedDB (web).

Readme

🧠 react-smart-query

Offline-first normalized data layer for React Native & Web

npm version License: MIT


⚡ Quick Example

Get started in seconds. It looks just like the tools you already know, but with superpowers.

import { useSmartQuery } from 'react-smart-query';

const { data, isLoading } = useSmartQuery({
  queryKey: ["expenses"],
  queryFn: fetchExpenses
});

🚨 The Problem

TanStack Query (React Query) handles data fetching brilliantly. But as your app grows, real-world constraints start to show. Complex apps often struggle with:

  • Pagination + Mutation Bugs: Updating a single item buried inside page 3 of an infinite list requires complex, error-prone manual cache traversals.
  • Offline Sync: Surviving patchy networks and syncing user actions when they come back online.
  • Unnecessary Re-renders: UI components rendering more often than they need to.
  • Large List Updates: Finding and updating items in massive arrays without freezing the UI.

💡 The Solution

react-smart-query intercepts your API responses and stores them intelligently.

  • Adds offline-first support right out of the box.
  • Uses normalized storage (a flat dictionary) behind the scenes for lighting-fast updates.
  • Fixes pagination + mutation issues automatically. No more manual cache traversal!
  • Works on top of React Query. It enhances your existing setup without replacing it.

✨ Key Features

  • 📶 Offline-first caching (MMKV for mobile, IndexedDB for web)
  • 🚀 Normalized data structure ({ byId, allIds } map) for O(1) updates
  • 🧠 Smart diff updates (minimal, surgically precise re-renders)
  • 📜 Infinite query with normalized pagination (no more page-splicing bugs)
  • 🌍 Global mutation system (add/update/remove from anywhere, without hooks)
  • 📱 Cross-platform support
  • 🛡️ Memory protection (maxItems to elegantly trim huge lists)

⚖️ Why Not Just TanStack Query?

React Smart Query takes the heavy lifting out of state mutability. It delegates the networking to TanStack Query and completely upgrades the storage.

| Feature | TanStack Query | react-smart-query | | :--- | :---: | :---: | | Offline queue | ❌ | ✅ | | Normalized cache | ❌ | ✅ | | Pagination + mutation fix | ❌ | ✅ | | Global mutations | ❌ | ✅ |


📦 Installation

Install the library alongside its peer dependencies:

npm install react-smart-query @tanstack/react-query react-native-mmkv

🚦 Quick Start

1. Setup

Just wrap your app like you normally would. Your data layer is instantly primed.

import { QueryClient, QueryClientProvider } from '@tanstack/react-query';

const queryClient = new QueryClient();

export default function App() {
  return (
    <QueryClientProvider client={queryClient}>
      <YourApp />
    </QueryClientProvider>
  );
}

2. Standard Query

import { useSmartQuery } from 'react-smart-query';

function UserProfile({ userId }) {
  const { data } = useSmartQuery({
    queryKey: ['users', userId],
    queryFn: () => api.getUser(userId),
    select: (res) => res.user,
  });

  return <Text>{data?.name}</Text>;
}

3. Infinite Query

This is where the magic happens. Mutating paged data is now effortless.

import { useInfiniteSmartQuery } from 'react-smart-query';

function Feed() {
  const { data, addItem } = useInfiniteSmartQuery({
    queryKey: ['feed'],
    queryFn: ({ pageParam }) => api.getFeed({ cursor: pageParam }),
    getNextCursor: (res) => res.nextCursor,
    select: (res) => res.items,
    getItemId: (item) => item.id,
    sortComparator: (a, b) => b.createdAt - a.createdAt,
  });

  // Adding an item automatically sorts it into the exact right place!
  const onNewPost = (post) => addItem(post);

  return <FlatList data={data} renderItem={...} />;
}

💼 Example Use Case

Scenario: An Expense Tracking App

Imagine a user is traveling through the subway and logs an expense.

  1. react-smart-query immediately intercepts this.
  2. It pushes the action to an Offline Queue.
  3. It performs a Global Mutation, inserting the new expense into the normalized store.
  4. Your Infinite List jumps to life—it finds the expense, uses your sortComparator via binary search to place it at exactly the top of the list, and triggers a surgically precise re-render.
  5. When the user exits the subway, the queue detects the network and syncs the expense to your server.

Perfect for: Expense Apps, Chat Apps, Social Feeds, and Dashboards.


🛠️ API Overview

  • useSmartQuery: Drop-in enhancement for viewing and caching standard API calls.
  • useInfiniteSmartQuery: The flagship hook. Takes paginated API chunks, flattens them, sorts them globally, and gives you addItem, updateItem, and removeItem helpers.
  • getSmartQueryActions: A global API to mutate data from outside of React components (e.g., from a push notification background handler).

🏗️ Architecture

       UI (React Components)
               ↓
       Smart Query Hooks
               ↓
    TanStack Query (Networking)
               ↓
 Normalized Cache + Offline Queue
               ↓
   Storage (MMKV / IndexedDB)

🕵️ Debug Tools

For power users, react-smart-query comes with built-in development inspection tools to see exactly how your data is normalizing.

import "react-smart-query/debug";
import { smartQueryDebug } from "react-smart-query";

// Prints the exact current state of the global { byId, allIds } maps to your console!
await smartQueryDebug.snapshot();

🤔 When to Use / Not Use

Use if:

  • You are building offline-first apps.
  • You have large, paginated lists.
  • You have high-frequency data updates (websocket chats, real-time feeds).

Avoid if:

  • You are building a very small app without offline needs.
  • Your data is purely static and never mutates locally.

🗺️ Roadmap

  • [ ] DevTools UI (Visual Inspector)
  • [ ] Built-in WebSocket sync adapter
  • [ ] Lightweight Plugin System

🤝 Contributing

We welcome contributions! Whether you're fixing a bug, adding a feature, or improving documentation, check out our repository and open a Pull Request.


📄 License

MIT © 2024 React Smart Query Team