GitHub

Everything external is a part you can swap.

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.

API

integrations

Run

Add what you need.

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.

01

Event workflows

React to any domain event in one entry

02

Storefront blocks

Add a block type the compiler then demands you finish

03

Product page modules

Place your own module into a PDP section

04

Admin modules

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 works

These are seams inside your own copy of the code. There is no versioned plugin API.

Inside integrations & api.

01

Outbound webhooks

Subscribe external systems to store events, with every delivery logged and endpoints that keep failing disabled automatically.

02

Service API keys

Issue scoped API keys so your own tools, such as an ERP or a warehouse system, can read and write against the store.

03

Catalog import

Import an existing catalog from Shopify, with each import run recording exactly what came across.

04

Self-hosting

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.

Modules that sit next to this one

MIT licensed · self-hosted

Integrations & API ships with Litestore. So does everything else.

Get the source