Skip to content
brix.v2 stable

Search documentation

70 guides

Documentation menu
Docs / Getting started / Application typesRead Markdown ↗

Build managed React applications

Create and operate a browser-only managed React SPA or Contentful App with Brix-owned runtime and Vite integration.

Create a managed React SPA

Create a standalone app:

brix create react-app customer-portal
cd customer-portal
brix dev

From a Brix workspace root, omit --version; the new member uses the workspace's exact Brix version and a bare name is placed under apps/:

brix create react-app customer-portal
brix doctor#customer-portal
brix dev#customer-portal

The generated manifest declares brix.project: "react-application". It has a root index.html, src/main.tsx, src/App.tsx, src/brix.ts, and this Vite configuration:

import { defineBrixReactConfig } from "@brix/react/vite";

export default defineBrixReactConfig();

defineBrixReactConfig configures the managed React JSX runtime, deduplicates React and ReactDOM, supplies browser-safe aliases, and adds the Brix Vitest configuration. Its optional vite value accepts the supported Brix Vite escape hatch as an object or a function of the Vite environment:

export default defineBrixReactConfig({
  vite: ({ mode }) => ({
    base: mode === "production" ? "/portal/" : "/",
    define: { __APP_VARIANT__: JSON.stringify(mode) },
  }),
});

Do not replace managed entries, output, JSX settings, or Brix plugins through that escape hatch.

Use the managed runtime

Import React APIs and types from @brix/react, not directly from react. Mount through the client entry point:

import { StrictMode } from "@brix/react";
import { createRoot } from "@brix/react/client";
import { App } from "./App.tsx";

const element = document.getElementById("root");
if (!element) throw new Error("React application root is missing");

createRoot(element).render(
  <StrictMode>
    <App />
  </StrictMode>,
);

The root adapter also exports Brix's React bindings:

  • useApi for contract-aware requests
  • useSignal and useComputed for React signal integration
  • useStorage, useLocalStorage, and useSessionStorage
  • TranslationProvider and createTranslationHooks
  • the supported React runtime, hooks, events, elements, and component types

Define browser-safe contracts with defineBrix in src/brix.ts:

import { defineBrix } from "brix/contracts";

export const brix = defineBrix();
export const { createApiContract, executeApi, getPath } = brix;

Application components can then combine project-bound contracts with React hooks:

import { useApi } from "@brix/react";
import { productApiContract } from "@commerce/contracts";

export function Product({ productId }: { productId: string }) {
  const request = useApi(productApiContract, {
    baseUrl: "https://api.example.com",
  });

  if (request.isLoading.value) return <p>Loading…</p>;
  if (request.isError.value) return <p>Request failed: {request.error.value?.message}</p>;
  if (request.data.value) return <h1>{request.data.value.name}</h1>;
  return (
    <button onClick={() => void request.execute({ params: { productId } })}>Load product</button>
  );
}

The contract package is a contextual application dependency: link it in a workspace before importing it. Consult API routes and the API reference for the installed useApi signature.

Understand the application boundary

A managed React application builds once to dist. It is not a Brix server application and has:

  • no Hono API or page route implementation
  • no SSR, createBrixApp, or Node start command
  • no Preact islands or hydration directives
  • no Panda integration; use the React application's chosen CSS approach
  • no managed Brix Storybook support

Shared contracts let the React browser call a separately deployed BFF; they do not make the deployments same-origin. Pass that BFF's deployed origin as baseUrl, and configure the BFF to allowlist the browser origin with its CORS middleware. See workspaces and the caching guide.

Create a Contentful App

Use the dedicated preset rather than adding Contentful packages by hand:

brix create contentful-app editorial-tools

Within a workspace:

brix create contentful-app editorial-tools

This remains a react-application, but records the Contentful integration and adds exact compatible SDK, Forma 36, icon, and app-script dependencies. The generated Vite config uses a relative base required by uploaded Contentful assets:

import { defineBrixReactConfig } from "@brix/react/vite";

export default defineBrixReactConfig({ vite: { base: "./" } });

Import the managed surfaces through Brix:

import { useEffect } from "@brix/react";
import { Button, GlobalStyles, Heading } from "@brix/react/contentful";
import { PlusIcon } from "@brix/react/contentful/icons";
import { init, type KnownAppSDK } from "brix/contentful/app";

The generated entry calls init, renders with its SDK, and handles the app configuration location. Preserve base: "./"; brix doctor reports drift. Continue with the Contentful guide.

Continue with integrate an external react host.