Getting Started with Boron
The official Next.js commerce framework for Prebit storefronts.
A different product from the Partner API section above
Everything above this point (OAuth, @prebit/sdk, Products/Collections
API) is for building third-party backend integrations — apps that
act on a merchant's store via OAuth with granted scopes. Boron is for
building the storefront itself — the actual shopping site — talking
to Prebit's public, unauthenticated Storefront API. Different audience,
different API, different trust model. @prebit/boron does not depend on
@prebit/sdk, and vice versa.
@prebit/boron is the equivalent of Shopify's Hydrogen, but native to
Next.js App Router instead of Remix: Server Components for reads, Server
Actions for mutations, cache tags, metadata, and static params — not a
hook-for-every-method port of a browser SDK.
Host anywhere
Boron doesn't require Prebit Cloud. Deploy to Vercel, Cloudflare, Docker,
Kubernetes, your own VPS — or Prebit Cloud when you want managed hosting.
Your code, your infrastructure, your choice: @prebit/boron only ever
talks to Prebit's public Storefront API over plain HTTP, with no
server-side dependency on any Prebit-specific runtime.
Quick start
npx create-boron-app my-store
cd my-store
npm install
cp .env.example .env.local # fill in NEXT_PUBLIC_PREBIT_STORE_ID
npm run devThis clones prebit-template-store —
a real Next.js app with working product/collection/cart pages already
wired up, not an empty shell.
From scratch
npm install @prebit/boron// app/products/[slug]/page.tsx
import { getProduct, getProductMetadata } from "@prebit/boron/server";
import { Product, VariantSelector, Money, Img } from "@prebit/boron/components";
export async function generateMetadata({ params }: { params: Promise<{ slug: string }> }) {
const { slug } = await params;
const product = await getProduct(slug);
return getProductMetadata(product);
}
export default async function ProductPage({ params }: { params: Promise<{ slug: string }> }) {
const { slug } = await params;
const product = await getProduct(slug);
return (
<Product product={product}>
<Img src={product.imageUrl} alt={product.name} width={600} height={600} />
<Money amount={product.price} />
<VariantSelector />
</Product>
);
}// app/layout.tsx — wrap once, at the root
import { CartProvider, AnalyticsProvider } from "@prebit/boron/client";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html>
<body>
<AnalyticsProvider>
<CartProvider>{children}</CartProvider>
</AnalyticsProvider>
</body>
</html>
);
}// proxy.ts — page-view/session tracking (see the Analytics page for why
// this runs here and not as a direct browser call)
import { trackPageView } from "@prebit/boron/server";
export const proxy = trackPageView;
export const config = {
matcher: ["/((?!_next/static|_next/image|favicon.ico|api/).*)"],
};Environment variables
NEXT_PUBLIC_PREBIT_STORE_ID=
NEXT_PUBLIC_PREBIT_API_BASE=https://admin.prebit.in
NEXT_PUBLIC_PREBIT_CHECKOUT_BASE=https://checkout.prebit.inRead directly via process.env inside @prebit/boron — no Context
Provider is needed just for config, since Next.js already inlines
NEXT_PUBLIC_* vars into both server and client bundles.
Package layout
@prebit/boron
├── server/ — getProduct, getProducts, getCollection, getCollections,
│ cache-tag builders, metadata/static-params helpers
├── client/ — CartProvider, useCart, useCheckout, useCustomer (stub)
├── components/ — Money, Img, Product, VariantSelector, Cart, Pagination,
│ OptimisticCart
└── actions/ — addToCartAction, updateCartItemAction,
removeCartItemAction, clearCartActionSee the Server, Client, Components, Actions, and Analytics reference pages for each.
Not implemented yet: search, useCustomer's real implementation,
theming. See @prebit/boron's own README.md for what a v2 could draw
from.