Skip to 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.

Run cargo add in your crate:

Terminal window
cargo add gpui-query

or add it by hand to Cargo.toml:

[dependencies]
gpui-query = "0.2.0"

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

Feature Default Pulls in What it gives you
core no serde only The transport-agnostic state machine (QueryResource, CachePolicy, …) with no GPUI dependency. Usable in non-GPUI code or tests.
client yes core + gpui The QueryClient registry and its type-partitioned buckets.
hook no client The use_query / use_mutation hooks you call from views.
persist no client + hook + serde_json + thiserror Async persistence: the Persister trait, QueryClient::persist_with, the free hydrate function, and the typed (de)serializer registries. See Persistence.

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.2.0", features = ["hook"] }
Terminal window
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). Add persist when you want to save and restore the cache across restarts (gpui-query = { features = ["hook", "persist"] }).

Two standalone crates extend gpui-query without adding dependencies to the core:

  • gpui-query-persist is a reference disk adapter. FilePersister atomically writes a PersistSnapshot to disk (JSON or bincode) with a tolerant load. cargo add gpui-query-persist. See Persistence: reference adapter.
  • gpui-query-http turns a server’s Cache-Control header into a CachePolicy (“server wins”) and layers an in-memory HttpCache over any HTTP backend. cargo add gpui-query-http. See HTTP cache headers.

Both depend on gpui-query with a narrow feature set and publish independently.

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;
fn setup_app(cx: &mut gpui::App) {
cx.set_global(QueryClient::new());
}

QueryClient::new() uses the default policies (Ttl { ttl_ms: 60_000 }, LatestWins). Override them with with_policies and tune the garbage-collection window with with_gc_time:

use gpui_query::client::QueryClient;
use gpui_query::{CachePolicy, core::RequestPolicy};
let client = QueryClient::with_policies(
CachePolicy::Ttl { ttl_ms: 60_000 },
RequestPolicy::LatestWins,
)
.with_gc_time(600_000); // 10 minutes (default is 5)
cx.set_global(client);

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.

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