Skip to main content

Installation

gpui-query is a Cargo crate. This page covers adding it to a GPUI project, choosing the right feature flags, and installing a QueryClient as a GPUI Global so the hooks can share a single cache.

Add the dependency

Run cargo add in your crate:

cargo add gpui-query

or add it by hand to Cargo.toml:

[dependencies]
gpui-query = "0.1"
note

gpui-query depends on gpui as a workspace dependency. It does not ship gpui itself — your app already brings gpui in, and gpui-query links against the same version.

Feature flags

The crate is split into three layers, each behind a feature flag:

FeatureDefaultPulls inWhat it gives you
corenoserde onlyThe transport-agnostic state machine (QueryResource, CachePolicy, …) with no GPUI dependency. Usable in non-GPUI code or tests.
clientyescore + gpuiThe QueryClient registry and its type-partitioned buckets.
hooknoclientThe use_query / use_mutation hooks you call from views.

client is on by default, so cargo add gpui-query is enough to get the registry. To use the ergonomic hooks from your components, enable the hook feature:

[dependencies]
gpui-query = { version = "0.1", features = ["hook"] }
cargo add gpui-query --features hook

You almost always want hook in an application. Reach for core alone when you need the state machine without a GPUI dependency (a library, a CLI that reasons about cached state, or unit tests).

Set up the QueryClient

QueryClient is a GPUI Global. Install it once during app setup — from then on, every hook routes resource creation through it for shared caching, deduplication, and garbage collection.

use gpui_query::client::QueryClient;
use gpui_query::{CachePolicy, core::RequestPolicy};

fn setup_app(cx: &mut gpui::App) {
cx.set_global(QueryClient::new(
// Default freshness for every query.
CachePolicy::Ttl { ttl_ms: 60_000 },
// Default behavior for concurrent fetches on the same resource.
RequestPolicy::LatestWins,
));
}

QueryClient::new takes the default cache and request policies. Tune the garbage-collection window and the default mutation retry policy with builders:

use gpui_query::client::QueryClient;
use gpui_query::{CachePolicy, RetryPolicy, core::RequestPolicy};

let client = QueryClient::new(
CachePolicy::Ttl { ttl_ms: 60_000 },
RequestPolicy::LatestWins,
)
.with_gc_time(600_000) // 10 minutes (default is 5)
.with_retry_policy(RetryPolicy::no_retries()); // default retry for mutations

cx.set_global(client);
note

If a hook runs before a QueryClient is installed, it falls back to creating a standalone entity — there is no shared cache, no deduplication, and no GC. Always install the client during app startup.

Verify it is reachable

From any context, read the client back to confirm the global is set:

# use gpui_query::client::QueryClient;
# fn doc(cx: &gpui::App) {
let _client = cx.global::<QueryClient>();
# }

That is the entire setup: add the crate, enable hook, install a QueryClient global. With that in place, the Quick Start shows your first end-to-end query.

Next steps

  • Quick Start — define a fetcher, call use_query, render data.
  • Queries — the full use_query surface and QueryResource accessors.
  • CachingCachePolicy, deduplication, and GC in depth.