NAMCHE UI

Application integration

React and Vite with optional TanStack adapters, outside the UI core.

Vite application boundary

Start with a React + TypeScript Vite application and Tailwind v4. Configure @tailwindcss/vite in Vite and point both TypeScript and Vite's @ alias to src. Then follow Installation, importing the global stylesheet once in the application's entry point. The token package loads fonts; no Next.js APIs or theme provider are involved.

Keep the installed components/ui directory focused on primitives. Put compositions under features or components/recipes, route loaders in routes, and the OpenAPI-generated client in api/generated. Rust/Axum, SQLite, authentication and HTTP error mapping remain application concerns. None of these belong in a registry dependency.

TanStack Query adapter

This is application code, not a NAMCHE dependency. The generated client wrapper must reject unsuccessful HTTP responses and pass cancellation through to fetch. Adapt the client generator's actual response shape in that wrapper.

import { useQuery } from '@tanstack/react-query';
import { ProjectTable } from '@/features/projects/application-patterns';
import { listProjects } from '@/api/projects';

export function ProjectsRoute() {
  const query = useQuery({
    queryKey: ['projects'],
    queryFn: ({ signal }) => listProjects({ signal }),
  });
  // Keep cached data on screen when a background request fails.
  if (query.data !== undefined) return <ProjectTable state={{
    status: 'ready', projects: query.data,
    refreshing: query.isFetching, refreshError: query.isError,
  }} />;
  if (query.isError) return <ProjectTable state={{
    status: 'error', retry: () => { void query.refetch(); },
  }} />;
  return <ProjectTable state={{ status: 'loading' }} />;
}

For a mutation, pass save={name => mutation.mutateAsync({ name })} to ProjectDialog. In the application's mutation success callback invalidate ['projects']. Decide whether to wait for that refresh before closing the form; a refresh failure must not misreport an already-successful write as a failed save. Keep mutation errors typed at the API boundary, and map field errors into user-facing validation messages.

TanStack Router adapter

Ordinary route links use Router's Link. Use the Base UI render contract when composing a button-shaped link:

import { Link } from '@tanstack/react-router';
import { Button } from '@/components/ui/button';

<Button nativeButton={false} render={<Link to="/projects">Projects</Link>} />

nativeButton={false} tells Base UI that the rendered element is an anchor. Use route IDs and params defined by your application's generated route tree; these docs do not prescribe a route schema. Put URL selection, search params, route loading and error boundaries in the application. QueryClientProvider and RouterProvider also belong in its shell, never in NAMCHE components.

The TanStack examples are adapter sketches: those packages are intentionally not dependencies of this repository, so compile them in the consuming app. The framework-neutral recipe source is compiled and checked here.

On this page