Nano Stores Query

Nano Stores Query logo

Services & Skills

Share on

  • Small: 1.59 KB (minified and gzipped).
  • Built-in cache: Features stale-while-revalidate caching from HTTP RFC 5861; users rarely see unnecessary loaders or stale data.
  • Revalidate cache: Automatically revalidate on interval, refocus, and network recovery; or revalidate it manually.
  • Nano Stores first: Finally, fetching logic outside of components. Plays nicely with store events, computed stores,router, and the rest.
  • Transport agnostic: Use GraphQL, REST codegen, plain fetch, or anything that returns Promises.

First, define the stores to set up dynamic fetching:

// core/stores.ts
import { nanoquery } from '@nanostores/query';

export const [createFetcherStore, createMutatorStore] = nanoquery({
  fetcher: (...keys: string[]) => fetch(keys.join("")).then((r) => r.json()),

export const $currentPostId = atom<string | void>();
export const $currentPost = createFetcherStore<{ id: string; content: string }>(
  ["/api/post/", $currentPostId]

Then, use it just like a regular atom: you can compose it with all the instruments Nano Stores provides and connect it to components if you like:

// components/Post.tsx

 * Use lifecycle events to run side-effects, or computed stores to have derived
 * state.
onSet($currentPost, ({ newValue: { data: post } }) => {
  if (post) trackPostVisitToAnalytics(post);

export const Post = () => {
  // And use plain ol' hooks to get data in the component
  const { data: post } = useStore($currentPost);
  if (!post) return null;

  return <article>{post.content}</article>;

In the same orbit

Explore more open source projects

How can we help you?

Martians at a glance
years in business

We transform growth-stage startups into unicorns, build developer tools, and create open source products.

If you prefer email, write to us at