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

# Quickstart

> From a production build to prioritized findings, a snapshot, and a baseline.

## Requirements

* Next.js 15 or 16, App Router
* Node 20+
* A **production** build. crust refuses to measure `next dev` - dev output is unminified,
  unbundled and HMR-laden, so any number taken from it is fiction.

Install `@moumensoliman/crust` as a development dependency, or use `npx` directly. The package name differs
from the executable; the product and executable are both named `crust`.

## 1. Build, then analyze

<CodeGroup>
  ```bash npm theme={null}
  next build
  npx @moumensoliman/crust analyze
  ```

  ```bash pnpm theme={null}
  next build
  pnpm dlx @moumensoliman/crust analyze
  ```
</CodeGroup>

```text theme={null}
crust cfdcf50068722687  next 16.2.12 · webpack · 3 routes

Fix first

  1. /dashboard only 39% of this route is in the static shell
     ↳ cookies() at app/dashboard/page.tsx:18 - in <Theme>
     → <Theme> is postponed by that call. Isolate it inside Suspense, or accept the
       hole when the data must be per-request.

  2. /products/[slug] only 45% of this route is in the static shell
     ↳ uncached fetch at lib/http.ts:3 - in <ProductGallery>
     → Add `use cache` above that read to pull <ProductGallery> back into the shell.

Route              First load   Shell  Mode
/                    543.2 kB    100%  static
/dashboard           527.4 kB     39%  partial
                    ↳ cookies() at app/dashboard/page.tsx:18
                    ✂ <Theme> - cookies() at app/dashboard/page.tsx:18
/products/[slug]     543.2 kB     45%  partial
```

The findings come first because a new project has no baseline yet. The complete route table follows
so you can inspect every route, including ones that need no action.

The snapshot is written to `.perf/` using one file per build. Two branches can record builds without
editing a shared history file.

### Reading the columns

* **First load** is the JavaScript downloaded on the first visit, including shared root chunks.
* **Shell** is the share of visible rendered output outside pending Suspense boundaries.
* **Mode** is `static`, `partial`, `isr`, `dynamic`, or `handler`.
* Indented `↳` lines name the reason for a mode or hole.
* `✂` names a component that was postponed out of the shell.

## 2. See it visually

```bash theme={null}
npx @moumensoliman/crust report --open
```

A single self-contained HTML file: summary figures, the route table, and per-route detail with the
modules, dependencies, client boundaries and holes. No server, no integration, nothing external.

## 3. Compare against a baseline

After a change, rebuild and diff:

```bash theme={null}
next build
npx @moumensoliman/crust diff main
```

```text theme={null}
crust diff  cfdcf50068722687 -> 4a80239769ea8b93

/products/[slug] ▼  543.2 kB  -
    static -> partial
    shell 100% -> 45%
    cause: uncached fetch at lib/http.ts:3
    introduced by <ProductGallery>
```

<Tip>
  `crust diff` accepts a build id, a git SHA, a branch name, or `HEAD~3`. History is walked
  topologically, so a snapshot recorded later on another branch is never mistaken for an ancestor.
</Tip>

The two builds must use the same bundler, Next.js major, and snapshot schema. If they do not, crust
names the incompatibility and refuses to assign a cause.

## Unlock per-file attribution

Route sizes, rendering modes, dynamic-route blame and shell composition all work out of the box.
Tracing bytes to a specific **file** needs source maps in the production build:

```ts next.config.ts theme={null}
export default {
  productionBrowserSourceMaps: true,
}
```

Most projects do not have this on, so this is usually the difference between *"this route is
2.8 MB"* and *"`packages/features/src/course/…` is 340 kB of it"*.

<Warning>
  Without maps crust still reports every route total and the full shell analysis - it says the
  attribution is unavailable rather than guessing. Turn maps on in a dedicated analyze build if you
  would rather not ship them.
</Warning>

## Next steps

<CardGroup cols={2}>
  <Card title="Understand regressions" icon="code-compare" href="/docs/concepts/regressions">
    Automatic checks, explicit ceilings, comparability, and intentional exceptions.
  </Card>

  <Card title="Add the CI check" icon="circle-check" href="/docs/guides/ci">
    Regression enforcement, budgets, a PR comment, and history on an orphan branch.
  </Card>
</CardGroup>
