Spree: three beta releases in eight days, and multi-tenant behind a paywall
Open Source Platform for DTC, B2B Commerce, Marketplaces & Omnichannel. REST APIs, TypeScript SDKs, and production-ready Next.js storefront. Self-host it. Own your data. No vendor lock-in. Zero platform fees.
At a glance
- What is it?
- A BSD 3-Clause commerce platform pairing a Ruby backend with a TypeScript workspace of SDKs, a React admin dashboard and a Next.js storefront. As of the current branch, 6.0.0 exists only as beta2, beta3 and beta4 released within a week of each other, and the multi-tenant SaaS use case is the single item the open source core does not cover.
- Who is it for?
- Adopt Spree when you want one backend serving several surfaces or regions, since channels and markets model that as configuration rather than separate deployments, and when the marketplace primitives you need are in the open source core. Do not adopt it for multi-tenant SaaS without budgeting for the Enterprise Edition, and do not pin a stable 6.0 yet, because the newest tags are beta2, beta3 and beta4 from the same week.
- Can I use it commercially?
- Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly Ruby, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 15, 2026, and from our analysis. They are not legal advice.
Editorial analysis
6.0.0 exists only as beta2, beta3 and beta4 from the same eight days
The three most recent releases are v6.0.0.beta2 on 2026-09-17, v6.0.0.beta3 on 2026-09-24 and v6.0.0.beta4 on 2026-09-24. Beta3 and beta4 landed on the same day, about four hours apart.
There is no stable 6.0.0 tag in that list. If you are starting a new deployment, the newest stable line available to you is whatever shipped before the 6.0.0 beta sequence began.
This is worth pausing on, because the marketing framing in the README is about the current state of the platform rather than the version you can install. The features described in detail, the REST API, the SDKs, the dashboard and the storefront, are all real and all in this repository. What you cannot do today is pin a stable 6.x.
Beta tags also behave differently from stable ones in ways that affect operations. They are pre-release identifiers, so tooling that resolves the highest matching version will skip them unless you ask for them explicitly, and they carry no compatibility promise between one beta and the next. beta3 and beta4 four hours apart is a fast-moving target, not a slow one.
The branch itself is not idle. The last push to main was on 2026-09-25, the day after beta4. Plan your upgrade path around a moving 6.0 line rather than assuming you can hold a version indefinitely.
Multi-tenant SaaS is the one use case the open source core does not cover
The README opens the use case section with a claim that is worth reading closely. Marketplace features are described as all in the open-source core: seller onboarding with configurable requirement checklists, orders split per seller at completion, a flexible commission engine, a payout ledger with Stripe Connect, and a dedicated Seller Panel.
Then the multi-tenant SaaS entry is marked with an Enterprise superscript and says it requires the Enterprise Edition, with a link to the pricing page. Each tenant gets its own isolated store covering catalog, orders, customers, payment methods and branding, and staff can manage several tenants.
So the boundary is drawn between one platform with many sellers, and one platform with many tenants. Marketplace, B2B and wholesale, headless and omnichannel, and cross-border are all presented as shipping under the BSD 3-Clause licence in this repository. Multi-tenancy is not.
The distinction is not cosmetic. Sellers on a marketplace share one catalog and one set of staff permissions with a split order flow. Tenants on a SaaS platform need data isolation between customers who share nothing, plus per-tenant branding and staff scoping. If your requirement is the second thing, the open source core does not get you there and the pricing page is part of your evaluation, not a follow-up.
Everything else in the features section is prefaced by the statement that it ships in this repository under the BSD 3-Clause licence, which makes the Enterprise entry the single carve-out in an otherwise uniform open source offering.
create-spree-app needs Node.js 24 and Docker, and the Ruby server is a separate clone
The quick start is a single command:
npx create-spree-app@latest my-storeThe stated result is a working local Spree in five minutes, setting up the backend, the React admin dashboard and optionally the Next.js storefront in one project. The requirements are Node.js 24 or newer and Docker running, so a developer without a container runtime cannot follow this path at all.
Now compare that with how this repository develops against itself, because the two are different. The root package.json is private and its server:create script does not scaffold anything: it runs git clone on a separate starter repository, removes the cloned .git and .gitignore, and writes an environment file containing a SPREE_PATH pointing at the parent and a SECRET_KEY_BASE generated with openssl rand -hex 64.
That tells you the shape of a contribution. You do not run the Ruby application from this checkout directly; you clone a starter, point it at your working copy of spree, and drive it through Docker Compose. The scripts named server:dev, server:build, server:restart, server:stop and server:teardown all wrap Compose files under server/ and scripts/, with an optional Meilisearch overlay.
So there are two audiences with two different paths. Users of the platform run create-spree-app. Contributors to it run server:create against spree-starter. Only the first is documented as a five minute setup.
A preinstall hook makes pnpm mandatory, and the Ruby and TypeScript halves share one repo
The root package.json opens with a guard rather than a build script:
"preinstall": "npx only-allow pnpm",npm install fails before it does anything else. That is a deliberate choice, and it is enforced rather than documented, which is the right way to do it.
What it reveals is the repository layout. Alongside the Ruby application in spree/ sits a pnpm workspace with pnpm-workspace.yaml, a pnpm lockfile, packages/, turbo.json and biome.json. The scripts are all turbo passthroughs: dev, build, test, lint, lint:fix, format, typecheck and clean.
GitHub reports Ruby as the primary language, and it is, but the JavaScript side is not incidental. The SDK packages, the dashboard and the storefront starter all live in that workspace, which is why turbo and a workspace definition exist at all. A single turbo test run is what verifies both halves.
For a contributor this is a two toolchain checkout. Ruby with Bundler for the application, pnpm with turbo for the packages, and a linter that is biome rather than RuboCop for the JavaScript side. The generated application you get from create-spree-app is a simpler world, because it consumes the published packages rather than building them.
One more file is worth noticing: CHANGELOG.md is present at the root, alongside a .changeset/ directory, which is the convention for accumulating unreleased change entries before they are compiled into that file.
Three typed SDKs and three kinds of key, and choosing one is a scoping decision
The API story is built around three audiences rather than one. A complete REST API serves storefronts, admins and sellers, and it comes with publishable keys, scoped secret keys, rate limiting and an OpenAPI 3.0 specification. Three typed clients sit on top: @spree/sdk for the store, @spree/admin-sdk for admin and @spree/seller-sdk for seller.
Three credentials for three audiences is the design decision here. A publishable key belongs in a browser bundle, a secret key belongs on a server, and a seller key belongs with a marketplace vendor. Scoping them separately is what lets a seller-facing integration touch seller resources without being handed an admin credential.
The rate limiting and the OpenAPI 3.0 spec are the parts that matter operationally. The spec means the surface is described in a machine-readable form, which is what makes generating a client or writing tests against it practical. Rate limiting means you have to design for it, and that is a different code path from assuming an internal service.
For an adopter the practical consequence is that picking an SDK is picking a blast radius. Start with the store SDK for a headless build, because it is the narrowest. Reach for admin only when you are writing tooling rather than a storefront. Treat the seller SDK as the one that matters only if marketplaces are in scope, which is also when the commission engine and the payout ledger become relevant.
The admin dashboard has a plugin seam for nav, routes, columns and slots
The React admin dashboard is described as a Vite and React single page application built on TanStack Router and Query, with shadcn/ui and Tailwind. The extension story is the part worth noting, because it is explicit about what you do not have to do.
It is extendable with plugins, without forking, and the plugin surface is enumerated: nav entries, routes, table columns and slot widgets. Four concrete extension points.
That list is narrow enough to be honest and wide enough to cover most customisation. Navigation and routes cover adding a section. Table columns cover changing what a list shows. Slot widgets cover inserting something into an existing screen, which is how you add a panel to a page somebody else designed.
The dashboard ships with a matching Seller Panel for marketplace vendors, built the same way. Both are built from the repository's server scripts, which compile a Vite bundle and set a base path so the two can be served from one backend at different prefixes.
What the plugin model does not give you is a way to change how an existing screen renders internally. If a list needs different query logic rather than different columns, or a form needs a different submission flow, you are past the seam. At that point the choice is to fork the dashboard or move that work into the API, and the second is usually cheaper.
spree api schema and spree api endpoints explore the API offline
The CLI package @spree/cli sits in packages/cli and does four things: boots the stack, runs generators and migrations, tails logs, and calls the Admin API directly with get, post, patch and delete commands.
The examples in the README are concrete:
spree dev # boot the project (web + worker + db)
spree generate api_resource Brand name:string description:rich_text # Creates full API endpoints, models and database schema for a Brand resource
spree api get /orders -q status_eq=complete --limit 10 # query the Admin APIThe generator is the notable one. Naming a resource and its fields produces full API endpoints, models and a database schema. That is a scaffolding step across all three layers at once, which is a large amount of work removed, and also a large amount of generated code that becomes yours to maintain.
Two subcommands exist for working without a server: spree api endpoints and spree api schema explore the full API offline. For anyone integrating against Spree without a running instance, that is the fastest route to understanding the surface.
One line deserves attention before you script against this. The CLI is described as working hands-free for AI agents, with zero-config credentials in local dev. That is a local development affordance. It means the credential handling you are relying on while developing is not the credential handling you will want in production, and the README scopes the behaviour to local development rather than presenting it as a general property.
Channels split the surfaces and Markets split the regions
Two configuration concepts carry most of the multi-surface story, and they divide along different lines.
Channels are per surface. You run web storefronts, mobile apps, points of sale, B2B panels and marketplaces off one backend, and each of those gets its own catalog, pricing, payment methods and order attribution through a channel. The Next.js storefront is described as one such surface, production-ready and open source, built with Next.js 16, React 19 and TypeScript, meant to be forked and customised rather than consumed as a dependency.
Markets are per region. A market bundles currency, language, payment methods and shipping, so each customer sees a localized storefront from a single platform. Translations for product content, EU Omnibus price history and customs duties are built in rather than bolted on.
Both being configuration is the real payoff. A brand selling in three currencies through two channels does not run three deployments, and the order attribution built into channels is what makes per-surface reporting possible afterwards.
The cost is that you have to model these before you model the storefront. Channels decide which catalog a given surface sees and which prices apply, so a catalogue structure that ignores them tends to need reworking once a second surface exists. B2B adds a third axis on top, with price lists carrying volume tiers, customer groups, and companies holding locations, contacts and tax exemptions, and storefronts gated to approved buyers. That is a lot of modelling up front, and it is the main reason a Spree build takes longer than the five minute install suggests.
Editorial conclusion
Adopt Spree when you want one backend serving several surfaces or regions, since channels and markets model that as configuration rather than separate deployments, and when the marketplace primitives you need are in the open source core. Do not adopt it for multi-tenant SaaS without budgeting for the Enterprise Edition, and do not pin a stable 6.0 yet, because the newest tags are beta2, beta3 and beta4 from the same week. Verify Node.js 24 and a running Docker before you start, since create-spree-app requires both, and confirm your SDK choice among store, admin and seller.
Frequently asked questions
How do I set up Spree locally?
Run npx create-spree-app@latest with your project name. It sets up the Spree backend, the React admin dashboard and optionally the Next.js storefront in one project. You need Node.js 24 or newer installed and Docker running.
Is there a stable Spree 6.0 release to pin?
Not in the current release list. The three most recent tags are v6.0.0.beta2 on 2026-09-17, v6.0.0.beta3 and v6.0.0.beta4 both on 2026-09-24, so 6.0.0 is still a pre-release line and beta tags carry no compatibility promise between versions.
Does the open source Spree support multi-tenant SaaS?
Multi-tenant SaaS is the one use case marked Enterprise and it requires the Enterprise Edition. Marketplace, B2B and wholesale, headless and omnichannel, and cross-border are described as shipping in the repository under the BSD 3-Clause licence. Everything in the features section is stated to ship in this repository, with multi-tenancy as the carve-out.
What does the Spree CLI do and which credentials does it use?
@spree/cli boots the stack, runs generators and migrations, tails logs, and calls the Admin API with get, post, patch and delete commands. It also offers spree api endpoints and spree api schema to explore the API offline. Zero-config credentials are described as applying to local dev, not to production.
Which TypeScript SDKs does Spree ship?
Three typed clients: @spree/sdk for the store, @spree/admin-sdk for admin and @spree/seller-sdk for seller. They sit on a REST API covering storefronts, admins and sellers, with publishable keys, scoped secret keys, rate limiting and an OpenAPI 3.0 specification.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/spree-spree)