# Tooling

> Reference for the build-side pieces: the @apricot/react Expo config plugin, withApricot for Metro, and the apricot-models CLI (optimise and inspect .glb files) with its budgets and Node API.

## Expo config plugin

```json title="app.json"
{
  "expo": {
    "plugins": ["@apricot/react"]
  }
}
```

It applies:

| Setting | Why |
| --- | --- |
| The `react-native-webgpu` plugin | The GPU canvas |
| Android `minSdkVersion` at least 26 (keeps a higher value) | react-native-webgpu uses Android 8.0 hardware-buffer APIs |
| iOS `CADisableMinimumFrameDurationOnPhone` | Lets the frame loop run at 120 Hz on ProMotion iPhones |

Run `npx expo prebuild` (or a new dev build) after adding it.

## Metro: `withApricot`

```js title="metro.config.js"
const { getDefaultConfig } = require("expo/metro-config");
const { withApricot } = require("@apricot/metro");

module.exports = withApricot(getDefaultConfig(__dirname));
```

It:

- adds `glb` and `gltf` to the asset extensions, so `require("./car.glb")` works (exported as `ASSET_EXTENSIONS`);
- resolves every `three` and `three/webgpu` import to three's WebGPU build, so the bundle holds one copy of three. Keep any other resolver you had: `withApricot` calls it for everything else.

A `.gltf` must be self-contained (buffers and images embedded); a separate `.bin` cannot be found at runtime. Convert to `.glb` with `apricot-models`.

## `apricot-models` CLI

From `@apricot/metro`. Install it as a dev dependency and run it with `npx`.

### Optimise

```sh
npx apricot-models <file-or-folder>... [-o <out-folder>]
```

Each `.glb` or `.gltf` input (folders: every model inside) becomes `<name>.glb` in the output folder.

> [!WARNING]
> Without `-o`, the output is written **next to the input**, so a `.glb` input is replaced. Keep your source files in another folder (`models/`) and write to the app's assets (`-o assets/models`).

What it does:

- removes duplicate and unused data, welds vertices;
- **quantizes** meshes (`KHR_mesh_quantization`): smaller files with no runtime decoder;
- decodes Draco and meshopt input on your computer (Hermes has no WebAssembly, so the phone cannot);
- rejects KTX2 / Basis textures with a clear message (use PNG or JPEG);
- converts `.gltf` with a separate `.bin` into one `.glb`;
- prints the size before and after, and budget warnings.

### Inspect

```sh
npx apricot-models inspect <file> [--json]
```

Prints triangles, parts (name, triangles, materials; heaviest first), materials with how many parts use them, textures (size, type, bytes), animation clip names and budget warnings. These are the names `<Model materials>`, `joints`, `animations` and model kits select by. `--json` prints a `ModelSummary` plus `warnings`.

### Budgets

For one hero model on a mid-range phone:

| Budget | Value |
| --- | --- |
| Triangles | 150,000 |
| Texture side | 2048 px |
| Texture memory | 8 MB total |

Beyond these the CLI warns; the model still works but may cost frame rate or memory. Each separate mesh also costs about 80 µs per frame (measured on a Galaxy A55): merge parts in Blender where you can, and use `<Instances>` for repeats.

### Node API: `@apricot/metro/models`

```ts
import { BUDGET, budgetWarnings, createModelIO, optimizeModel, summarize } from "@apricot/metro/models";
```

| Export | Description |
| --- | --- |
| `optimizeModel(input, { quantize? })` | `Promise<{ bytes, report: { before, after, byteLength, warnings } }>`. `input` is `.glb` bytes or a gltf-transform `Document` |
| `summarize(document)` | A `ModelSummary`: meshes, materials, textures, vertices, triangles, parts, material names, texture list, animations, extensions |
| `createModelIO()` | A gltf-transform `NodeIO` with every extension and the Draco and meshopt decoders |
| `BUDGET` | `{ triangles: 150000, textureSide: 2048, textureBytes: 8388608 }` |
| `budgetWarnings(summary)` | Warning strings for a summary over budget |

## Related

- [Installation](https://matthiasbrandolin.dev/apricot/installation).
- [Loading models](https://matthiasbrandolin.dev/apricot/guides/models#1-prepare-the-file).
- [Performance](https://matthiasbrandolin.dev/apricot/concepts/performance).
