spree/spree
Open-source headless eCommerce platform with REST API, TypeScript SDK, and Next.js storefront for cross-border, B2B or marketplace eCommerce.
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".
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
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
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)
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
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
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
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
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
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
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
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
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.
- 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]
- 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]
- 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]
- 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)
- 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.
packages/sdk/src/types/generated/Product.tsGenerated 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
packages/sdk/src/types/generated/Cart.tsGenerated 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
packages/sdk/src/types/index.tsHand-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
packages/create-spree-app/src/types.tsInterface 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
packages/cli/src/types.tsInterface 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
TypeScript interfaces generated from Ruby serializers — provides type safety contract between frontend and backend
Key-value pairs controlling Docker ports, Rails secrets, and service URLs — read by CLI commands and Docker Compose
Feedback Loops
- HTTP request retry with exponential backoff (retry, balancing) — Trigger: Network errors or 5xx responses from Spree API. Action: createRequestFn retries with exponential backoff and jitter. Exit: Success response, non-retryable error, or max attempts reached.
- Type regeneration on serializer changes (self-correction, reinforcing) — Trigger: Git pre-commit hook detects changes in spree/api/app/serializers/. Action: Runs Typelizer to regenerate TypeScript types and Zod schemas, stages generated files. Exit: All type definitions updated and committed.
Delays
- Docker service startup (warmup, ~30-120 seconds) — CLI init command polls health endpoint every 3 seconds until Spree backend responds, preventing premature database seeding
- Template download during scaffolding (async-processing, ~Variable based on network speed) — Project creation waits for backend and storefront templates to download from GitHub before generating project structure
Control Points
- SPREE_PORT (env-var) — Controls: Port number for Rails backend and all CLI operations — affects Docker port mapping and API URL construction. Default: 3000 (default)
- Retry configuration (runtime-toggle) — Controls: HTTP request retry behavior including max attempts, delay calculation, and which errors trigger retries. Default: 3 max attempts with exponential backoff
- Package manager selection (architecture-switch) — Controls: Which package manager (npm, yarn, pnpm) is used for dependency installation during project scaffolding. Default: Auto-detected from environment
- SPREE_VERSION_TAG (env-var) — Controls: Docker image tag for Spree backend — allows switching between versions (latest, stable, specific version). Default: latest
Technology Stack
Primary language for SDK packages and CLI tools — provides type safety for API interactions
CLI framework used in both cli and create-spree-app packages for command parsing and help generation
Service orchestration for Rails backend, PostgreSQL, Redis, and Meilisearch during development
Process execution library used by CLI tools to run Docker commands and system operations
Code generation tool that converts Ruby serializers to TypeScript interfaces and Zod schemas
Testing framework for MDX-to-Markdown conversion functions in docs package
Monorepo build system that orchestrates builds, tests, and dev servers across packages
Package manager with workspace support for managing dependencies across the monorepo
Key Components
- StoreClient (adapter) — Main client class for storefront API operations — handles cart management, product browsing, checkout flow, and customer authentication with configurable locale defaults
packages/sdk/src/store-client.ts - AdminClient (adapter) — Main client class for admin API operations — manages products, orders, customers, and store configuration with admin authentication
packages/admin-sdk/src/admin-client.ts - createRequestFn (factory) — Creates HTTP request functions with retry logic, authentication, error handling, and response transformation — shared by both SDK packages
packages/sdk-core/src/request.ts - detectProject (resolver) — Detects Spree project context by finding docker-compose.yml and reading port configuration from .env files
packages/cli/src/context.ts - scaffold (orchestrator) — Orchestrates new project creation — downloads backend template, optionally adds Next.js storefront, configures Docker, generates environment files, and starts services
packages/create-spree-app/src/scaffold.ts - Command dispatcher (dispatcher) — Main CLI entry point that registers all commands (dev, stop, init, seed, etc.) and handles command routing with error handling
packages/cli/src/index.ts - convertContent (transformer) — Transforms Mintlify MDX documentation to plain Markdown by converting JSX components (callouts, tabs) to GitHub-style alerts and sections
packages/docs/scripts/convert.js - dockerCompose (executor) — Executes Docker Compose commands with project context — handles service management (up, down, logs) and Rails tasks (seed, console) within containers
packages/cli/src/docker.ts
Package Structure
TypeScript SDK for Spree's admin API — provides type-safe client for managing products, orders, and store configuration.
Command-line interface for managing Spree Commerce projects — handles Docker orchestration, seeding, and development workflows.
Project scaffolding tool that creates new Spree Commerce projects with backend, storefront, and Docker configuration.
Documentation build system that converts Mintlify MDX files to plain Markdown for AI agent consumption.
TypeScript SDK for Spree's storefront API — handles cart management, checkout, product browsing, and customer authentication.
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 CodeSeaRelated 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 Karolina Sarna.