spree/spree

Open-source headless eCommerce platform with REST API, TypeScript SDK, and Next.js storefront for cross-border, B2B or marketplace eCommerce.

15,354 stars Ruby 8 components

12 hidden assumptions · 5-stage pipeline · 8 components

Like any codebase, this fullstack makes assumptions it never checks — most are routine. The ones worth your attention are below.

Headless eCommerce platform with Ruby backend, TypeScript SDKs, and developer tooling

The system operates as a multi-package toolkit around a Ruby on Rails eCommerce backend. Type definitions flow from Ruby serializers through Typelizer to generate TypeScript interfaces. The storefront SDK uses these types to provide cart management and checkout flows, while the admin SDK handles inventory operations. CLI tools manage Docker orchestration and project scaffolding, reading configuration from environment files and Docker Compose manifests.

Under the hood, the system uses 2 feedback loops, 2 data pools, 4 control points to manage its runtime behavior.

A 8-component fullstack. 2171 files analyzed. Data flows through 5 distinct pipeline stages.

Hidden Assumptions

Most of what this code assumes is routine. These 3 are the ones most likely to cause trouble here. The rest are minor; they're under "Show everything".

Worth your attention first

When Ruby serializers evolve (add required fields, change types, rename properties), existing TypeScript client code silently receives malformed data or fails at runtime with no compile-time warning

Worth your attention first

Invalid ports (like 'abc' or '99999') cause Docker services to fail to start with cryptic errors, while used ports cause silent conflicts where CLI commands target wrong services

Worth your attention first

If backend template changes service names or structure, generated projects have broken Docker configurations and CLI commands fail with 'service not found' errors

Show everything (9 more)
Resource

GitHub backend template repository is accessible and contains expected directory structure with docker-compose.yml in root — no rate limiting, authentication, or repository structure changes

If this fails: Network failures or GitHub API limits cause scaffold process to hang or fail partway through, leaving incomplete projects that appear valid but miss critical backend components

packages/create-spree-app/src/scaffold.ts:downloadBackend
Temporal

Spree backend health endpoint (/health) becomes available within reasonable time (implied max ~6 minutes based on 3-second intervals) and responds with expected format

If this fails: If backend takes longer to initialize or health endpoint changes format, CLI hangs indefinitely or proceeds with unready services, causing database seeding and other operations to fail mysteriously

packages/cli/src/commands/init.ts:health check polling
Scale

HTTP retry logic with exponential backoff (3 attempts max) is sufficient for all network conditions, and that 5xx errors are always transient and worth retrying

If this fails: During high load or persistent server issues, requests fail after only 3 attempts even when longer retry sequences would succeed, while persistent 503s from overloaded servers waste resources on futile retries

packages/sdk-core/src/request.ts:createRequestFn
Shape

Backend always returns checkout validation errors in exactly 3 fields (step, field, message) with string types, and that step names are consistent across different checkout flows

If this fails: If backend adds metadata fields or changes step naming conventions, checkout validation becomes unreliable and storefront displays malformed error messages to users

packages/sdk/src/types/index.ts:CheckoutRequirement
Domain

Generated SECRET_KEY_BASE values have sufficient entropy for production security and that Ruby on Rails secret generation requirements don't change

If this fails: If entropy is insufficient or Rails changes secret format requirements, generated projects have weak session security or fail to start with cryptic Rails errors

packages/create-spree-app/src/templates/env.ts:generateSecretKeyBase
Contract

MDX components follow consistent naming patterns (Info/Warning/Tip) and self-closing syntax, with no nested JSX or dynamic attributes that would break regex-based conversion

If this fails: Complex MDX content with nested components or attributes gets mangled during conversion, producing broken documentation with missing or malformed sections

packages/docs/scripts/convert.js:convertContent
Ordering

Command registration order doesn't affect functionality and all commands can be safely registered in any sequence without dependencies between them

If this fails: If commands have hidden dependencies (like 'init' must run before 'seed'), the registration order might mask these dependencies until runtime conflicts occur

packages/cli/src/index.ts:command registration
Environment

Package manager detection correctly identifies npm/yarn/pnpm from environment, and that detected package manager has compatible command interfaces for dependency installation

If this fails: Wrong package manager detection leads to failed dependency installations during project scaffolding, while version incompatibilities cause cryptic error messages during setup

packages/create-spree-app/src/index.ts:detectPackageManager
Temporal

Typelizer digest hash changes only when actual type structures change, not when comments or non-semantic content changes in Ruby serializers

If this fails: False positive regeneration wastes build time and creates noisy commits, while false negatives leave stale types that diverge from backend reality without detection

packages/sdk/src/types/generated/index.ts:Typelizer digest

Open the standalone hidden-assumptions report for spree →

How Data Flows Through the System

The system operates as a multi-package toolkit around a Ruby on Rails eCommerce backend. Type definitions flow from Ruby serializers through Typelizer to generate TypeScript interfaces. The storefront SDK uses these types to provide cart management and checkout flows, while the admin SDK handles inventory operations. CLI tools manage Docker orchestration and project scaffolding, reading configuration from environment files and Docker Compose manifests.

  1. Type generation from Ruby serializers — Typelizer reads Ruby serializer classes from spree/api/app/serializers/ and generates TypeScript interfaces, storing them in packages/sdk/src/types/generated/ and packages/admin-sdk/src/types/generated/ [Ruby serializer classes → Product, Cart, Order, Customer types]
  2. SDK client initialization — createClient or createAdminClient functions instantiate StoreClient or AdminClient with API URL, authentication tokens, and locale defaults, creating a configured request function via createRequestFn [ClientConfig or AdminClientConfig → StoreClient or AdminClient]
  3. API request execution — Client methods call the request function created by createRequestFn, which handles HTTP requests with retry logic, authentication headers, error transformation into SpreeError instances, and response deserialization [Request parameters and options → Typed API responses]
  4. CLI project detection — detectProject function scans for docker-compose.yml and reads SPREE_PORT from .env file to build ProjectContext, which all CLI commands use to locate services and configure operations [File system paths → ProjectContext] (config: SPREE_PORT, SECRET_KEY_BASE)
  5. Project scaffolding — create-spree-app prompts user for configuration, downloads backend and storefront templates, generates environment files with generated secrets, configures Docker Compose files, and optionally starts services [ScaffoldOptions → Complete project structure] (config: SPREE_PORT, SECRET_KEY_BASE, SPREE_VERSION_TAG)

Data Models

The data structures that flow between stages — the contracts that hold the system together.

Product packages/sdk/src/types/generated/Product.ts
Generated TypeScript interface with fields like name: string, slug: string, price: Price, variants: Variant[], media: Media[], categories: Category[]
Generated from Ruby serializers via Typelizer, consumed by both storefront SDK for product display and admin SDK for inventory management
Cart packages/sdk/src/types/generated/Cart.ts
Generated TypeScript interface with line_items: LineItem[], total: string, currency: string, warnings: CartWarning[], shipping_address: Address, billing_address: Address
Created when user adds products, updated through line item operations, validated during checkout, converted to Order on completion
CheckoutRequirement packages/sdk/src/types/index.ts
Hand-written interface with step: string, field: string, message: string — represents unsatisfied checkout prerequisites
Computed by backend during checkout validation, consumed by storefront to show required fields to complete purchase
ScaffoldOptions packages/create-spree-app/src/types.ts
Interface with directory: string, storefront: boolean, sampleData: boolean, start: boolean, port: number, packageManager: PackageManager
Built from CLI arguments and interactive prompts, consumed by scaffold function to configure new project structure
ProjectContext packages/cli/src/types.ts
Interface with mode: 'docker', projectDir: string, port: number — represents detected Spree project environment
Detected by reading docker-compose.yml and .env files, used by all CLI commands to locate project and determine ports

System Behavior

How the system operates at runtime — where data accumulates, what loops, what waits, and what controls what.

Data Pools

Generated type definitions (file-store)
TypeScript interfaces generated from Ruby serializers — provides type safety contract between frontend and backend
Project environment configuration (file-store)
Key-value pairs controlling Docker ports, Rails secrets, and service URLs — read by CLI commands and Docker Compose

Feedback Loops

Delays

Control Points

Technology Stack

TypeScript (runtime)
Primary language for SDK packages and CLI tools — provides type safety for API interactions
Commander.js (framework)
CLI framework used in both cli and create-spree-app packages for command parsing and help generation
Docker Compose (infra)
Service orchestration for Rails backend, PostgreSQL, Redis, and Meilisearch during development
Execa (library)
Process execution library used by CLI tools to run Docker commands and system operations
Typelizer (build)
Code generation tool that converts Ruby serializers to TypeScript interfaces and Zod schemas
Vitest (testing)
Testing framework for MDX-to-Markdown conversion functions in docs package
Turborepo (build)
Monorepo build system that orchestrates builds, tests, and dev servers across packages
pnpm (build)
Package manager with workspace support for managing dependencies across the monorepo

Key Components

Package Structure

admin-sdk (library)
TypeScript SDK for Spree's admin API — provides type-safe client for managing products, orders, and store configuration.
cli (tooling)
Command-line interface for managing Spree Commerce projects — handles Docker orchestration, seeding, and development workflows.
create-spree-app (tooling)
Project scaffolding tool that creates new Spree Commerce projects with backend, storefront, and Docker configuration.
docs (tooling)
Documentation build system that converts Mintlify MDX files to plain Markdown for AI agent consumption.
sdk (library)
TypeScript SDK for Spree's storefront API — handles cart management, checkout, product browsing, and customer authentication.
sdk-core (shared)
Shared infrastructure for SDK packages — provides request handling, error types, and common utilities.

Explore the interactive analysis

See the full architecture map, data flow, and code patterns visualization.

Analyze on CodeSea

Related Fullstack Repositories

Frequently Asked Questions

What is spree used for?

Headless eCommerce platform with Ruby backend, TypeScript SDKs, and developer tooling spree/spree is a 8-component fullstack written in Ruby. Data flows through 5 distinct pipeline stages. The codebase contains 2171 files.

How is spree architected?

spree is organized into 4 architecture layers: Core Infrastructure, Client SDKs, Developer Tools, Ruby Backend. Data flows through 5 distinct pipeline stages. This layered structure keeps concerns separated and modules independent.

How does data flow through spree?

Data moves through 5 stages: Type generation from Ruby serializers → SDK client initialization → API request execution → CLI project detection → Project scaffolding. The system operates as a multi-package toolkit around a Ruby on Rails eCommerce backend. Type definitions flow from Ruby serializers through Typelizer to generate TypeScript interfaces. The storefront SDK uses these types to provide cart management and checkout flows, while the admin SDK handles inventory operations. CLI tools manage Docker orchestration and project scaffolding, reading configuration from environment files and Docker Compose manifests. This pipeline design reflects a complex multi-stage processing system.

What technologies does spree use?

The core stack includes TypeScript (Primary language for SDK packages and CLI tools — provides type safety for API interactions), Commander.js (CLI framework used in both cli and create-spree-app packages for command parsing and help generation), Docker Compose (Service orchestration for Rails backend, PostgreSQL, Redis, and Meilisearch during development), Execa (Process execution library used by CLI tools to run Docker commands and system operations), Typelizer (Code generation tool that converts Ruby serializers to TypeScript interfaces and Zod schemas), Vitest (Testing framework for MDX-to-Markdown conversion functions in docs package), and 2 more. A focused set of dependencies that keeps the build manageable.

What system dynamics does spree have?

spree exhibits 2 data pools (Generated type definitions, Project environment configuration), 2 feedback loops, 4 control points, 2 delays. The feedback loops handle retry and self-correction. These runtime behaviors shape how the system responds to load, failures, and configuration changes.

What design patterns does spree use?

4 design patterns detected: Generated type safety bridge, Shared infrastructure with package-specific clients, CLI commands with Docker orchestration, Template-based project scaffolding.

Analyzed on April 20, 2026 by CodeSea. Written by .