DotNet Query

A TanStack Query-inspired async data fetching and state management library for .NET and Blazor.

DotNet Query brings the battle-tested data-fetching patterns of TanStack Query to the .NET ecosystem. It gives you predictable loading, error, and success states out of the box — powered by Rx.NET observables, so everything is composable, lazy, and reactive by default.

If you have ever found yourself writing the same isLoading / hasError / data boilerplate over and over, or wrestling with cache invalidation after a form submission, DotNet Query is here to help.


Features

  • Queries — fetch async data with automatic caching, background refetching, and stale-while-revalidate semantics.
  • Infinite queries — paginated and "load more" data fetching with <InfiniteSuspense> / <InfiniteTransition>.
  • Mutations — execute data-modifying operations with lifecycle callbacks and automatic cache invalidation on success.
  • Reactive state — every query and mutation exposes IObservable streams for composable async pipelines.
  • Smart caching — configurable stale time and cache time control when data is refetched and when it is evicted.
  • Query deduplication — identical keys share a single cached query instance; no redundant requests.
  • Retry logic — one attempt by default, fail-fast; plug in exponential backoff or any other policy via IRetryHandler.
  • Observability — OTel-compatible distributed tracing, metrics, and structured logging using only BCL APIs.
  • Blazor components — <Suspense> and <Transition> components for declarative query rendering.
  • DevTools — <QueryDevTools> live cache inspector component for development.
  • MVVM view models — bindable INotifyPropertyChanged view models for MAUI, WPF, WinUI, UNO Platform, and Avalonia.
  • CSR / SSR support — QueryExecutionMode controls Singleton (WebAssembly) vs Scoped (Server-Side Rendering) DI lifetime.
  • DI integration — first-class support for Microsoft.Extensions.DependencyInjection.

Quick Example

// Register in Program.cs
builder.Services.AddDotNetQuery(options =>
{
    options.StaleTime = TimeSpan.FromMinutes(1);
});

// In your service or component
var query = queryClient.CreateQuery(new QueryOptions<int, UserDto>
{
    KeyFactory = id => QueryKey.From("users", id),
    Fetcher    = (id, ct) => userService.GetByIdAsync(id, ct),
});

query.SetArgs(42);

query.Success.Subscribe(user => Console.WriteLine($"Hello, {user.Name}!"));
query.Failure.Subscribe(error => Console.WriteLine($"Oops: {error.Message}"));

Get Started

  • Introduction — understand the core concepts and motivation.
  • Getting Started — install and write your first query in minutes.
  • Guides — deep dives into queries, mutations, caching, Blazor, MVVM, and more.
  • Migrating to v2 — breaking changes and upgrade steps for 2.0.
  • API Reference — full generated API documentation.