ClickHouse React Hooks: Type-Safe Data Fetching Without the Boilerplate
@hypequery/react generates typed React hooks from the same query definitions that back your HTTP API. No manual useState/useEffect, no type drift between server and client.
Most React + ClickHouse setups look something like this:
This works. But the return type is any[], so every downstream use of data is untyped. The fetch URL is a string that can drift from the actual endpoint. Loading and error state is duplicated across every component that fetches data. When the query changes, the component has no way to know.
@hypequery/react replaces this pattern with generated hooks that are typed from the schema and shared with the same query definitions your API uses.
How it works
hypequery's query objects — the same ones you pass to serve({ queries }) — can also be used to generate React hooks. The hook knows the query's return type because it was inferred when you defined the query.
The hook handles loading, error, and data state. The return type is inferred from the query definition. When the schema changes and you regenerate types, any component using the hook gets a type error at compile time — not a runtime surprise.
What createHooks generates
createHooks() takes an object of query definitions and returns a hook per query. Pass { revenue }, get back { useRevenue }.
Each hook returns:
With parameters
If your query accepts inputs, the hook takes them as arguments:
With multi-tenancy
Pass tenant context via headers:
Tenant isolation lives at the query definition level — the hook just passes the header through. The component doesn't need to know about tenancy at all.
Before and after
Before — raw fetch, manual types, duplicated state logic:
After — generated hook, inferred types, zero boilerplate:
Getting started
@hypequery/react requires @hypequery/serve for the shared query definitions. If you're already using the serve layer, adding React hooks is a one-line change.
Related content