Client

React

useSession, Can, useLive, and useLiveQuery from okengine/client-react — React helpers over createClient.

okengine/client-react is a separate package so core okengine/client stays under the size budget. Hooks wrap the same typed client: session status, live SSE, and live resource lists with optimistic mutate.

For developers building React storefronts and ops consoles on top of createClient.

The one rule

Pass the same api you built with createClient. Hooks never open a second client factory — they subscribe, call Flows, and clean up on unmount.

Smallest Example

Create the client and session

web/src/session.ts
import { createClient } from "okengine/client";
import { vault } from "okengine/vault";
import { app } from "../../src/app";

export const api = createClient(app, vault.env("PUBLIC_API_URL") ?? "", {
  auth: { mode: "cookie", csrfConfigured: true },
});

Show the signed-in shopper in the header

web/src/AccountMenu.tsx
import { Can, useSession } from "okengine/client-react";
import { api } from "./session";

export function AccountMenu() {
  const { status, user, signOut } = useSession(api.auth!);

  if (status === "loading") return null;
  if (status === "unauthenticated") return <a href="/sign-in">Sign in</a>;

  return (
    <>
      <Can auth={api.auth!} all={["orders:write"]} fallback={null}>
        <a href="/fulfillment">Fulfillment</a>
      </Can>
      <button type="button" onClick={() => signOut()}>
        {user?.email}
      </button>
    </>
  );
}

Can / useAuthorize are UI-only — Gate on Flows remains real authz.

Progressive Patterns

import { useSession } from "okengine/client-react";

const { status, user, accessToken, refresh, signOut } = useSession(api.auth!);
FieldMeaning
status"loading" | "authenticated" | "unauthenticated"
userauth.me payload or null
accessTokenCurrent Bearer from memorySession (or null)
refresh()Re-run auth.me
signOut()session.clear() + unauthenticated

Package boundary

ExportPackageRole
createClient / api.liveokengine/clientTyped proxy + SSE subscribe
createAuthClient / memorySessionokengine/client/authSecure session orchestration
vault / vault.envokengine/vaultEnv + config contracts (subpath — not root)
useSession / useLive / useLiveQueryokengine/client-reactReact hooks (react optional peer)
subscribeLiveResourceokengine/client-reactNon-hook live resource stream helper

Prefer createAuthClient for cookie/Bearer sessions and method helpers. useLiveQuery accepts listPath to derive GET ${listPath}/live when live is omitted.

useLiveQuery options

OptionMeaning
enabledDefault true — idle when false
refreshKeyIdentity change → full re-subscribe
onAuthRefreshAfter auth.refresh() → new snapshot + replay

refetch() re-runs only the HTTP list read; reconnects always do a full subscribe-protocol cycle (new snapshot + replay). Event kinds and resume physics: Live.

Troubleshooting

Learn more

  • AuthmemorySession and gate denials
  • Liveapi.live, resume, live query kinds
  • Calling — envelopes and list pager
  • Signal · Live — server tape
  • Storelive: true resources

Next

On this page