Semaphor
Data Apps

Quickstart

Build a Semaphor Data App with the starter and your coding agent.

The fastest way to build a Semaphor Data App is to scaffold the starter, connect your coding agent to Semaphor, and ask the agent to build from a semantic domain.

This is the same flow shown inside Semaphor when you choose Build Data App from a domain.

1. Create The Starter

Run the bootstrapper from the folder where you want the app created:

npx create-semaphor-app@latest

Then start the local app:

cd semaphor-data-app
npm run dev

The generated app includes:

  • a Vite React Data App starter;
  • react-semaphor/data-app-sdk wiring;
  • Semaphor source components for query states, filters, KPI cards, server tables, and matrix tables;
  • local samples at /samples;
  • agent guidance files for building governed Data Apps.

You do not need a separate Semaphor component install step for the default path.

2. Authenticate Your Agent

Open the generated project in Codex or Claude Code.

For Codex:

codex mcp login semaphor

For Claude Code, open Claude Code in the project folder, run:

/mcp

Then authenticate the Semaphor server.

What authentication enables

The Semaphor Agent Plugin can inspect your project and semantic domains, generate a Data App contract, write local source files, validate the app, and help save or publish the result.

3. Ask The Agent To Build

Ask the agent to build from the semantic domain you want to use:

@Semaphor Build a Data App from the Sales Analytics domain.

The agent should:

  1. inspect the Semaphor domain and available governed fields;
  2. plan the app views, inputs, filters, and visual types;
  3. generate a deterministic Data App contract;
  4. build the React UI using the starter components;
  5. validate generated queries and the local app.

You can review the plan before implementation. A good plan should tell you what will be built, for example: KPI cards, trend charts, breakdown charts, matrix views, filters, and server-backed detail tables.

4. Preview And Iterate

Keep the local app running:

npm run dev

Then ask your agent for targeted changes:

@Semaphor Add a server-backed detail table for the selected facilities.
@Semaphor Add a date filter and apply it to every time-based view.
@Semaphor Validate this Data App and fix any generated contract issues.

The agent should use Semaphor validation before treating the app as ready.

Optional: Use A shadcn Preset

The starter ships with a working shadcn setup. If your team has a custom shadcn preset, pass the shadcn preset code during creation:

npx create-semaphor-app@latest my-data-app --shadcn-preset <preset-id>

<preset-id> is a shadcn preset from shadcn create, not a Semaphor package or component registry. Choose the preset at scaffold time so the app's own styling remains the source of truth.

Manual React Setup

Use manual setup when you are adding Semaphor to an existing React app or need full control over the Vite/shadcn initialization.

npm create vite@latest my-data-app -- --template react-ts
cd my-data-app
npm install react-semaphor

Import the Data App SDK from the package subpath:

import {
  SemaphorDataAppProvider,
  semaphor,
  useSemaphorInput,
  useSemaphorQuery,
} from 'react-semaphor/data-app-sdk';

Wrap your app with SemaphorDataAppProvider:

App.tsx
import { SemaphorDataAppProvider } from 'react-semaphor/data-app-sdk';

export function App({ token }: { token: string }) {
  return (
    <SemaphorDataAppProvider token={token}>
      <RevenueDashboard />
    </SemaphorDataAppProvider>
  );
}

Keep secrets server-side

Generate tokens server-side. Do not put project secrets, dashboard secrets, or long-lived tokens in browser code.

For existing apps, use your app's own UI components when possible. If you need reference implementations for query states, filters, KPI cards, server tables, or matrix tables, copy or adapt the matching source from the Data App starter. The SDK remains the runtime contract for queries, filters, execution status, and governed results.

Minimal Query Example

Use source-bearing fields. The source tells Semaphor which semantic dataset owns each field.

analytics.ts
import { semaphor } from 'react-semaphor/data-app-sdk';

export const orders = semaphor.source.semantic({
  domainId: 'commerce',
  datasetName: 'fact_orders',
});

export const revenue = semaphor.field.measure('revenue', {
  source: orders,
  aggregate: 'SUM',
});

export const revenueKpi = semaphor.metric({
  id: 'revenue_kpi',
  label: 'Revenue',
  source: orders,
  measures: [revenue],
  primaryMeasure: revenue,
});
RevenueKpi.tsx
import { useSemaphorQuery } from 'react-semaphor/data-app-sdk';
import { revenueKpi } from './analytics';

export function RevenueKpi() {
  const result = useSemaphorQuery(revenueKpi);

  if (result.isLoading) return <div>Loading revenue...</div>;
  if (result.error) return <div>{result.error.message}</div>;

  return (
    <section>
      <h2>Revenue</h2>
      <strong>{result.value}</strong>
    </section>
  );
}

For larger apps, prefer the generated Data App contract and starter components instead of hand-authoring every query and view.

Next Steps

On this page