npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

create-brainerce-store

v1.94.0

Published

Scaffold a production-ready e-commerce storefront connected to Brainerce

Readme

create-brainerce-store

Scaffold a production-ready e-commerce storefront connected to Brainerce — cart, checkout, variants, coupons, auth, SEO, and i18n wired out of the box.

npm create brainerce-store@latest my-store -- --connection-id vc_xxxxxxxx
# or
pnpm create brainerce-store my-store --connection-id vc_xxxxxxxx

Run it with no flags for a fully interactive setup. The CLI fetches your store's name, currency, language, and locales from the connection ID (vc_*, from your Brainerce dashboard), so the generated store matches the real channel from the first dev run.

The design

Every scaffold ships Atelier — a complete, AI-built storefront look (not just a color theme): warm editorial gallery with soft washes + glass surfaces, a floating hero collage, near-full-bleed product grid, styled popover dropdowns, a mini-cart drawer that opens on add-to-cart, and an RTL-safe fly-to-cart micro-interaction. Fully de-branded — driven by your store's name, catalog and dashboard content.

It's a starting point, not a lock-in: the entire look lives in src/ui/ + globals.css and is designed to be rewritten (see below). The shipped texts are vertical-neutral placeholder content (like any template's sample copy: they name no product category) — your catalog replaces the imagery automatically, and the copy (hero, story, footer tagline) lives in messages/ ready to be rewritten in your own voice by you or an AI session. On a brand-new store with no products yet, the homepage hero shows a designed placeholder that swaps for your first published products.

Blank-canvas mode

npm create brainerce-store@latest my-store -- --connection-id vc_xxx --canvas

--canvas ships src/ui/ as bare, semantic, essentially-unstyled skeletons (DESIGN ME markers included) with zero aesthetic opinion — commerce stays fully wired. It's the starting point for designing a storefront from scratch with an AI session, and the authoring substrate for new gallery designs. Canvas mode skips the design pack entirely.

AI-first by default

Every scaffolded store is ready to be redesigned by an AI coding session:

  • CLAUDE.md — auto-loaded by Claude Code; teaches the session the one rule (core/ is the platform's, ui/ is yours) before it touches anything.
  • AGENTS.md — the same context for other agentic tools.
  • /design <your art-direction brief> — a ready-made slash command that walks the full redesign: concept → implementation in ui/ → verification (tsc, real browser, screenshots, RTL checks).
  • AI-GUIDE.md — the design contract: file map, per-page hook contracts, verification loop, and hard-won RTL/i18n gotchas from real agency builds.

Architecture (core/ui)

  • src/core/ — platform-owned commerce: client, auth, providers, and data/behavior hooks that return state + handlers, never JSX. Don't modify.
  • src/ui/ — 100% replaceable presentation. Delete-and-rebuild is encouraged; the store keeps working.
  • src/app/ — thin routes composing the two (~10 lines each).
  • An ESLint boundary rule enforces the split in both directions.

Full details: TEMPLATE-ARCHITECTURE.md.

A cart that behaves, whatever you draw

The cart is the part of a storefront that goes wrong quietly, so the scaffold does not leave it to the design. StoreProvider runs the SDK cart store (brainerce/react, SDK 3.11.0 or newer) and useCart() / useCartPage() hand your src/ui the state and the actions; you draw it however you like:

  • Loading, error, empty, cart. The cart page renders by status in that order: a skeleton while loading (sized from the count remembered from the last visit), an error with a retry when the load fails (never "your cart is empty"), then the empty state, then the cart. Rebuilding src/ui keeps this as long as you keep the order.
  • Taps are never dropped. Quantity changes show at once, a burst of taps sends at most two requests, a failed change rolls back with an error, and nothing refetches the cart after a change (the response is the cart). The checkout button waits for pending changes.
  • Links do not reload the page. Use SmartLink from @/core/lib/navigation for every internal link (a router link for /paths, a plain anchor for external URLs). The store's lint rule (npm run lint) rejects a raw <a href> to an internal path under src/ui, because that is what throws away the loaded cart on every click.
  • Phones. A header cart count, a sticky checkout bar on the cart page, checkout fields with autocomplete / name / inputmode so the phone can fill them, and the chat widget is not mounted on /cart and /checkout.
  • Vercel. vercel.json pins the function region to fra1, next to the Brainerce API. Without it Vercel runs the proxy in iad1 and every cart call pays roughly 300 to 450 ms extra.

Check it in a real browser, without placing an order: npm run verify:storefront -- --url http://localhost:3000 --viewport 390x844 --slow (needs npm i -D playwright && npx playwright install chromium; the script is a copy of https://brainerce.com/verify-storefront.mjs). It exits with 1 when a check fails.

A wishlist, for guests and signed-in customers

Every product card and the product page carry a heart that saves the product for later, the header shows a heart with the saved count, and /wishlist lists the saved products (with "add all to cart", which skips what is sold out or needs an option). A guest's list stays in their browser and moves into their account when they log in; a signed-in customer's list is kept on their account, so it follows them to another device. It needs SDK 3.16.0 or newer. useWishlist() and useWishlistPage() give your src/ui the state; a failed load is shown as an error with a retry, never as an empty list.

Flags

| Flag | Description | Default | | ---------------------- | ------------------------------------------------------ | ------------------ | | --connection-id <id> | Brainerce sales-channel connection ID (vc_*) | prompted | | --defer-connection | Scaffold now, connect later with npm run connect | off | | --canvas | Bare unstyled src/ui/ skeletons for AI-driven design | off | | --language <lang> | Store language (en, he). One-way — see below | fetched from store | | --pkg-manager <pm> | npm, pnpm, yarn, bun | auto-detected | | --framework <fw> | nextjs (the only template; hidden from --help) | nextjs | | --api-url <url> | Brainerce API base URL (or BRAINERCE_API_URL env) | auto-discovered | | --no-git | Skip git initialization | git on | | --no-install | Skip dependency installation | install on |

Pass . as the project name to scaffold into the current directory.

--language is the one decision that cannot be changed after scaffolding: it picks which messages/ ship and the <html lang> / dir of every page. npm run connect and npm run setup refresh the store name and currency from the live channel, never the language — a store in the wrong language is re-scaffolded, not adjusted. Pass it explicitly when you know it (for example --language he for a Hebrew merchant); without a channel to read, a deferred scaffold assumes en.

Building first, connecting later

npm create brainerce-store@latest my-store -- --defer-connection --language he
cd my-store
npm run connect      # one browser approval; creates a store + channel if needed
npm run build        # NEXT_PUBLIC_* values are baked at build time

--defer-connection writes a placeholder channel id and skips the approval, so an AI builder can construct the whole storefront without stopping. The scaffold then knows no store: the name it bakes is the project directory name and the currency is USD. npm run connect writes the real channel id and runs npm run setup, which fetches the real name and currency into .env.local. At runtime the storefront prefers the live store name and currency from the API (server components, <title>, JSON-LD, the Open Graph card) and falls back to those .env.local values, then to the scaffold literal, so a connected store is branded correctly on the first request without a rebuild. The NEXT_PUBLIC_* fallbacks the client bundle carries are inlined at build time, though, so rebuild before deploying and restart a running dev server after connecting — connect says so when it finishes.

npm run connect -- --seed-products '[{"name":"Burr Grinder","basePrice":389}]' seeds a starter catalog in the same approval and reports, per product, whether it was created and whether it is published to this channel; a product that exists but is not published is named so you can publish it from the dashboard rather than add it twice. On PowerShell put the JSON in BRAINERCE_SEED_PRODUCTS instead of the flag.

Reading the connection

Before scaffolding, the CLI reads the channel from /api/vc/<id>/info so the generated project gets the real store name, currency and language rather than guesses. It reads https://api.brainerce.com; an internal environment is only used when you point at it yourself with --api-url or BRAINERCE_API_URL.

That endpoint checks the request's Origin against the channel's Domain and Allowed Origins, and the match counts the port. A Test channel with an empty Domain box accepts anything; one with localhost:3000 recorded will refuse a bare http://localhost. The CLI therefore presents http://localhost:3000 first and plain http://localhost second, and reports what every attempted URL said rather than only the last one.

A channel it cannot read is a hard stop, not a warning. Build-time NEXT_PUBLIC_* values are inlined into the client bundle and cannot be corrected at deploy time, so guessing USD / en here would ship a storefront quoting the wrong currency.

One exception: the API is unreachable, not wrong. When every attempt fails before any HTTP answer (no connection, or a timeout), which is what a sandboxed AI session with a restricted network looks like, and --language was passed, the scaffold carries on with your connection ID, a placeholder name and USD, and prints a warning. Run npm run setup from a normal network and rebuild to replace them. A 404, a 403 or a malformed answer still stops, and without --language it still stops too.

Requirements

Node ^20.19.0 || ^22.13.0 || >=24.0.0.

After scaffolding

cd my-store
pnpm dev          # store at http://localhost:3000

Want a unique look? Open the folder in Claude Code and run /design <your art-direction brief>.