Payments, email, storage, cache, analytics, and newsletters are integrations behind their own boundaries. Webhooks push events out, API keys let your systems in, and importers bring an existing catalog with you.
Write it into the same codebase. The compiler checks it fits.
lib/rules/workflows.ts
Durable{
event: "cart.abandoned",
name: "recover-abandoned-cart",
run: async (payload, step) => {
await step.sleep("settle", "3d")
await step.run("send-offer", () =>
queueEmail({ template: "cart-recovery", to: payload.email })
)
},
}A full cart-recovery flow. The three-day wait survives restarts and deploys, and the email is sent once.
React to any domain event in one entry
Add a block type the compiler then demands you finish
Place your own module into a PDP section
Inherit list, detail, mutations, activity, and permissions
Plus payment providers, outbound webhooks, swappable services, and checks that fail the build when an extension is wrong.
How extensibility worksThese are seams inside your own copy of the code. There is no versioned plugin API.
Subscribe external systems to store events, with every delivery logged and endpoints that keep failing disabled automatically.
Issue scoped API keys so your own tools, such as an ERP or a warehouse system, can read and write against the store.
Import an existing catalog from Shopify, with each import run recording exactly what came across.
Postgres, Redis, and S3 are yours to run, and you can deploy to Vercel, Docker, or your own server and export the database at any time.