Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/hypertekorg/hyperstack/llms.txt

Use this file to discover all available pages before exploring further.

useHyperstack

The primary hook for connecting to a Hyperstack and accessing its views and instructions.

Signature

function useHyperstack<TStack extends StackDefinition>(
  stack: TStack,
  options?: UseHyperstackOptions
): StackClient<TStack>

Parameters

stack
StackDefinition
required
The stack definition containing views and instructions
options.url
string
Override the stack’s embedded WebSocket URL (useful for local development)
useHyperstack(MY_STACK, { url: 'ws://localhost:3000' })

Return Value

The hook returns a StackClient object with:
views
object
Type-safe view hooks for all views defined in your stack
instructions
object
Instruction executors and mutation hooks for all instructions in your stack
zustandStore
UseBoundStore<StoreApi<HyperStackStore>>
Direct access to the Zustand store (for advanced use cases)
client
HyperStack<TStack>
The underlying HyperStack client instance
connectionState
ConnectionState
Current connection state: 'connected' | 'connecting' | 'disconnected' | 'error'
isConnected
boolean
Convenience boolean for connectionState === 'connected'
isLoading
boolean
True while establishing initial connection
error
Error | null
Connection error if any

Basic Example

import { useHyperstack } from 'hyperstack-react';
import { ORE_STREAM_STACK } from 'hyperstack-stacks/ore';

function Dashboard() {
  const { views, isConnected } = useHyperstack(ORE_STREAM_STACK);
  
  return (
    <div>
      <p>Connected: {isConnected}</p>
    </div>
  );
}

View Hooks

View hooks provide type-safe access to real-time data from your Hyperstack. They automatically subscribe to updates and re-render when data changes.

State Views

For views with mode: 'state', use the use() hook:
const { data, isLoading, error, refresh } = views.GroupName.viewName.use(
  { keyField: 'value' },  // Optional key
  { schema: MySchema }     // Optional options
);

Parameters

key
Record<string, string>
Optional key object to fetch a specific entity
options
ViewHookOptions
Configuration options:
  • enabled?: boolean - Enable/disable the subscription (default: true)
  • initialData?: T - Initial data while loading
  • schema?: Schema<T> - Zod schema for validation
  • refreshOnReconnect?: boolean - Re-fetch on reconnection

Return Value

data
T | undefined
The fetched entity, or undefined if loading or not found
isLoading
boolean
True while fetching initial data
error
Error | undefined
Error object if subscription failed
refresh
() => void
Manually trigger a re-subscription

List Views

For views with mode: 'list', use the use() or useOne() hooks:

Fetch Multiple Items

const { data, isLoading } = views.GroupName.viewName.use({
  key: 'optional_key',
  where: { status: 'active' },
  limit: 10,
  skip: 0,
  schema: MySchema
});
// data: T[] | undefined

Fetch Single Item

const { data, isLoading } = views.GroupName.viewName.use({
  take: 1,
  where: { id: 'abc' }
});
// data: T | undefined
Or use the useOne() convenience method:
const { data } = views.GroupName.viewName.useOne({
  where: { id: 'abc' },
  schema: MySchema
});
// data: T | undefined

List Parameters

key
string
Optional view key for partitioned data
where
Record<string, unknown>
Client-side filtering conditions:
where: { 
  status: 'active',
  count: { gte: 10, lte: 100 }
}
Supports: gte, lte, gt, lt for numeric comparisons
filters
Record<string, string>
Server-side filters (sent in subscription request)
limit
number
Client-side limit (applied after filtering)
take
number
Number of items to fetch (1 for single item)
skip
number
Number of items to skip (for pagination)
schema
Schema<T>
Zod schema for validation. Invalid items are filtered out.

Schema Validation

Use Zod schemas to validate and type data:
import { z } from 'zod';

const UserSchema = z.object({
  id: z.string(),
  name: z.string(),
  age: z.number()
});

type User = z.infer<typeof UserSchema>;

function UserList() {
  const { data } = views.Users.list.use({ 
    schema: UserSchema 
  });
  // data: User[] | undefined
  // Invalid items are automatically filtered out
}

Advanced Patterns

Conditional Fetching

function UserProfile({ userId }: { userId: string | null }) {
  const { data } = views.Users.byId.use(
    { id: userId ?? '' },
    { enabled: !!userId }
  );
  
  if (!userId) return null;
  if (!data) return <div>Loading...</div>;
  
  return <div>{data.name}</div>;
}

Client-Side Filtering

function ActiveUsers() {
  const { data } = views.Users.list.use({
    where: { 
      status: 'active',
      lastSeen: { gte: Date.now() - 3600000 } // Last hour
    }
  });
  
  return <ul>{data?.map(user => <li key={user.id}>{user.name}</li>)}</ul>;
}

Pagination

function PaginatedList() {
  const [page, setPage] = useState(0);
  const pageSize = 10;
  
  const { data, isLoading } = views.Items.list.use({
    skip: page * pageSize,
    limit: pageSize
  });
  
  return (
    <div>
      {data?.map(item => <div key={item.id}>{item.name}</div>)}
      <button onClick={() => setPage(p => p + 1)}>Next</button>
    </div>
  );
}

Manual Refresh

function RefreshableList() {
  const { data, refresh } = views.Items.list.use();
  
  return (
    <div>
      <button onClick={refresh}>Refresh</button>
      {data?.map(item => <div key={item.id}>{item.name}</div>)}
    </div>
  );
}

Zustand Integration

Access the underlying Zustand store for custom selectors:
function CustomSelector() {
  const { zustandStore } = useHyperstack(MY_STACK);
  
  const count = zustandStore(state => 
    state.entities.get('my_view')?.size ?? 0
  );
  
  return <div>Total items: {count}</div>;
}

Next Steps

Mutations

Learn how to execute instructions

Examples

See complete working examples

Build docs developers (and LLMs) love