Query Data In The Browser
Use the generated client for mutations and the browser query stack for typed reads.
Kizaki gives browser apps two complementary tools:
@kizaki/clientfor calling exposed server functions@kizaki/sdk/browserand@kizaki/reactfor browser-side query objects and live reads
Assign each tool a clear job and the architecture stays simple.
Use The Generated Client For Workflows
import { createProject } from "@kizaki/client";
await createProject("Docs rewrite");Use this path for mutations and business workflows. If an action changes the system, performs validation, coordinates multiple writes, or should stay behind a single typed entrypoint, it belongs in an exposed function called through the generated client.
Use Query Objects For Browser Reads
import { select } from "@kizaki/sdk/browser";
import { useQuery } from "@kizaki/react";
import { Project } from "@kizaki/schema";
const projectsQuery = select(Project)
.fields(Project.id, Project.name)
.orderBy("createdAt", "desc");
export function ProjectsList() {
const projects = useQuery(projectsQuery);
if (projects.status === "loading") return <p>Loading...</p>;
if (projects.status === "error") return <p>{projects.error?.message}</p>;
return (
<ul>
{projects.data.map((project) => (
<li key={project.id}>{project.name}</li>
))}
</ul>
);
}Recommended Split
- use generated client calls for actions
- use query objects for data shown in the UI
- let invalidation and live updates keep browser state current
Browser code stays simple. Server workflows stay centralized. Reads stay reactive without a second API surface.
If you know a screen should stay live, build the browser read with a query object from the start. You can fetch once today and add live updates later without rewriting the data model.
Continue with Add Realtime.