The integrations model
What an Appbrew integration is and how the app discovers it.
An integration is how third-party functionality (reviews, analytics, loyalty, checkout add-ons) plugs into an Appbrew app. Concretely, an integration is an npm package (partner-built ones publish under @app-brew/*; integrations Appbrew maintains for third-party services ship under @gauntlet/*) that can export:
- Blocks — React components for the UI the integration adds
- A register function — named
register{Name}Blocks, it adds those blocks to the app's block registry so config can place them - An analytics tracker — a class that receives every app event and forwards it to the third-party service
- Behavior extensions — action lifecycle hooks and module providers that change what the app does (Extending app behavior)
A package can ship any combination: a pure analytics integration exports only a tracker; a reviews integration exports blocks and their register function.
Blocks reach the registry through the app extension host from @gauntlet/brewery (platform 0.27.0 and later):
import { app } from '@gauntlet/brewery'
import { AcmeReviews } from '@app-brew/acme-reviews'
app.components.register('block', 'acme-reviews', AcmeReviews)Packages keep exporting a register{Name}Blocks function too: that is what the app scaffold generates and what hosts on 0.26 and earlier consume.
The manifest
Every integration package declares a manifest in its package.json under the appbrew key. The manifest makes the integration configurable without anyone reading your code. It drives the merchant-facing settings form and tells the platform how the package behaves.
{
"name": "@app-brew/acme-reviews",
"appbrew": {
"settings": [
{ "key": "apiKey", "title": "API key", "type": "text", "required": true, "secret": true },
{ "key": "storeId", "title": "Store ID", "type": "text", "required": true }
],
"configKey": "acme-reviews",
"requiresNativeBuild": false,
"dynamicForm": false
}
}Prop
Type
Mark credentials with secret: true so the platform handles them as secrets.
How settings reach your code
When a merchant fills in the form, the values are written into the app's config under integrations.<configKey>. Your code reads them back with the settings hooks:
import { useIntegrationSettings } from '@gauntlet/state'
interface AcmeReviewsSettings {
apiKey: string
storeId: string
}
const settings = useIntegrationSettings<AcmeReviewsSettings>('acme-reviews')
if (!settings?.apiKey) return nullThe same values are available to trackers through the app config passed at initialization.
requiresNativeBuild
Most integrations are pure JavaScript: enabling one is a config change, live on the next app launch. But if your package pulls in a native module (a native SDK, for instance), the app binary itself must change, so enabling it requires a store release rather than just a config change. Set requiresNativeBuild: true so the platform knows the difference. Keep integrations JS-only where you can; merchants can then adopt them instantly.
Go deeper
- Build an integration — the end-to-end workflow
- Manifest schema reference — every field, exactly

