> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nightshift.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Apps

> Real, hosted data applications — built by your agent, governed by Nightshift

Nightshift Apps are real-time, stateful applications built and deployed through
Nightshift's remote build system. Claude uses our MCP server as a development
environment: it writes the application code, submits it, and Nightshift compiles, checks,
and hosts it — no local toolchain involved. A published app lives at
`apps.nightshift.sh/<app-id>/` where anyone you've [shared it with](/sharing) can open it.

## How an app gets built

Ask Claude for an app ("build me a revenue dashboard with a region filter") and this is
what happens under the hood:

1. **Claude inspects your warehouse** — listing objects and describing schemas so it
   writes queries against your real tables, not guesses.
2. **It writes a small React app** using the Fiber SDK (more below) and submits the
   source to Nightshift's build service.
3. **Nightshift compiles it against your live warehouse.** Every query in the app is
   type-checked against the actual schema — a misspelled column or invalid SQL fails the
   build with the warehouse's own error, *before* anything ships. Claude reads the errors,
   fixes the source, and resubmits.
4. **On success, the app is live** — hosted, versioned, and ready to open.

This loop is why apps built by an agent are trustworthy: nothing reaches production
unless it compiles cleanly against your real data.

## The Fiber SDK

Application code is written with **Fiber**, our React SDK for governed data apps. Fiber
lets code define SQL queries with bound parameters, get precisely typed rows back, and
render them with a built-in set of charts, tables, and KPI components — which is exactly
the feedback loop that helps Claude drive toward working software quickly.

A flavor of what that code looks like:

```tsx theme={null}
const revenueByMonth = defineQuery(`
  SELECT strftime(sale_date, '%Y-%m') AS month, sum(amount) AS revenue
  FROM sales WHERE ($region = 'all' OR region = $region)
  GROUP BY 1 ORDER BY 1
`)

function App() {
  const [region, setRegion] = useAppState("region", "all")  // filter state, synced to the URL
  const q = useQuery(revenueByMonth, { region })
  return <LineChart query={q} x="month" y="revenue" title="Revenue" />
}
```

Queries are static and parameterized (never string-built), filter state lives in the URL
so any view of the app is shareable by link, and apps can even define managed read/write
tables for their own state.

<Note>
  Developers can also build Fiber apps by hand with a local toolchain —
  `npx @nightshift-sdk/create-fiber-app` scaffolds a Vite project, and `fiber publish`
  ships it to the same hosting. If you're interested in how Fiber works under the hood,
  read more [here](https://nightshift.sh/fiber).
</Note>

## Identity: development vs. published

Like everything in Nightshift, apps are tied to our [policy system](/policies). While
Claude is building, its queries run under *your* identity (or the scoped token you've
given it) — it can only see what you can see.

Publishing changes that. A published app no longer makes queries as you — it runs under
**its own identity**, and what it's allowed to do is frozen at publish time into what we
call the **manifest**.

The manifest is a frozen-in-time set of queries (and, for read/write apps, table
operations) extracted from the app's source and vetted under the publisher's access. At
runtime, the hosted app can execute *only* manifest entries — arbitrary SQL from a
browser is simply not runnable. This is a security feature, and it's what makes sharing
apps with many users safe.

You can think of an app as a composed view: people you share it with see the data the app
presents, without needing (or receiving) access to the underlying tables.

If that sounds like a lot — don't worry. There's nothing you need to do to get this
behavior; it all happens automatically on every publish.

## Versions

Every publish creates an immutable **version** carrying the exact source, the built
bundle, and the manifest. The live URL always serves the current version; older versions
remain pinned and inspectable. In the [console](https://console.nightshift.sh), an app's
detail page shows a live preview, its published source and manifest, and the full version
history — so you can always answer "what exactly is this app allowed to run?"

<Note>
  Creating an app requires the `app:create` capability. If Claude authenticates as you
  through the standard flow, it acts with your access — which is usually the convenient and
  reasonable choice. Mint a scoped [token](/policies#tokens) instead when you want tighter
  control.
</Note>

## Next steps

* [Sharing](/sharing) — give teammates access to run or manage an app
* [Policies](/policies) — the grant model apps are built on
* [Organizing site analytics data](/organizing-site-analytics-data) — an end-to-end
  example that finishes with a published app
