TIDE • Konfigurasi

Migrating from TanStack Query to Tide

Step-by-step migration guide from TanStack Query (React/Solid Query) to Tide micro-data layer.

Migrating to Tide

Learn how to replace 40KB TanStack Query with 2.8KB Tide without losing reactivity, optimistic mutations, or caching power.

If you know TanStack Query, the mental model maps seamlessly. The key difference is that Tide is WebSocket-first: real-time push streams and sessionStorage persistence are built-in primitives rather than separate plugins.

Concept Mapping

TanStack QueryTide FrameworkBenefit
useQuery({ queryKey, queryFn })createTide({ key, url })Eliminates redundant fetch boilerplate
queryClient.invalidateQueries()mutate(key, updater) or refetch()Direct signal mutation with auto WS sync
staleTime: 30000staleTime: 30_000Identical SWR timing semantics
cacheTime: 300000cacheTime: 300_000In-memory LRU with automatic prune
Plugin @tanstack/query-persist-clientpersist: true (default)Built-in 0ms revisit via sessionStorage

Code Comparison

TanStack Query (Before)

tsx
import { createQuery, useQueryClient } from '@tanstack/solid-query';

export function TodoIsland() {
  const queryClient = useQueryClient();
  const todos = createQuery(() => ({
    queryKey: ['todos'],
    queryFn: async ({ signal }) => {
      const res = await fetch('/api/todos', { signal });
      if (!res.ok) throw new Error('Fetch failed');
      return res.json();
    },
    staleTime: 30_000,
  }));

  return (
    <div>
      {todos.isLoading && <p>Loading...</p>}
      <ul>
        {todos.data?.map(item => <li key={item.id}>{item.text}</li>)}
      </ul>
    </div>
  );
}

Tide Framework (After)

tsx
import { createTide } from '@uikode/tide';
import { For, Show } from 'solid-js';

export function TodoIsland() {
  const todos = createTide<Array<{ id: string; text: string }>>({
    key: 'todos',
    url: '/api/todos',
    wsPath: 'data.todos', // WebSocket push updates this automatically
    staleTime: 30_000,
  });

  return (
    <div>
      <Show when={!todos.loading()} fallback={<p>Loading...</p>}>
        <ul>
          <For each={todos.data() ?? []}>
            {(item) => <li>{item.text}</li>}
          </For>
        </ul>
      </Show>
    </div>
  );
}

Eliminating WebSocket Glue Code

In TanStack Query, synchronizing WebSocket messages requires manual useEffect or createEffect listeners that call queryClient.setQueryData.

With Tide, passing wsPath: 'data.todos' or a custom ws: (msg) => msg.type === 'todo_updated' ? msg.payload : null automatically merges incoming frames into the active signal without writing any event dispatcher logic.