> ## Documentation Index
> Fetch the complete documentation index at: https://spreecommerce.org/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

> Learn how to customize every part of the Spree stack

Spree is a flexible platform allowing you to customize every part of it to suit your business needs. This guide presents customization options **in order of recommendation** - start from the top and only move down if simpler options don't meet your needs.

## Quick Reference

| What you want to do                                | Recommended approach                            |
| -------------------------------------------------- | ----------------------------------------------- |
| Change store settings (currency, zones, languages) | [Store Settings](#store-settings)               |
| Tweak Spree behavior globally                      | [Configuration](#configuration)                 |
| React to model changes (sync, notifications)       | [Events & Subscribers](#events-and-subscribers) |
| Notify external services                           | [Webhooks](#webhooks)                           |
| Swap core services (cart, checkout, etc.)          | [Dependencies](#dependencies)                   |
| Add admin menu items                               | [Admin Navigation](#admin-extensions)           |
| Add sections to admin forms                        | [Admin Partials](#admin-extensions)             |
| Add searchable/filterable fields                   | [Ransack Configuration](#search-and-filtering)  |
| Add associations/validations to models             | [Decorators](#decorators) (last resort)         |

<AccordionGroup>
  <Accordion title="Store settings" defaultOpen>
    **Best for:** Changing currency, shipping zones, languages, and other business settings.

    There's a lot of Store settings you can change in the admin panel without touching the code.

    Go to **Admin > Settings**

    <img src="https://mintcdn.com/spreecommerce/cQFxCIv2IPZLev6h/images/spree_admin_store_settings.png?fit=max&auto=format&n=cQFxCIv2IPZLev6h&q=85&s=fed7039a39b22539535ecaabbaa46ddb" alt="Spree Admin Store Settings" width="2582" height="1582" data-path="images/spree_admin_store_settings.png" />
  </Accordion>

  <Accordion title="Configuration">
    **Best for:** Tweaking Spree's behavior globally without modifying source code.

    Global application configuration allows you to customize various aspects of Spree:

    ```ruby config/initializers/spree.rb theme={"theme":"night-owl"}
    Spree.config do |config|
      config.allow_guest_checkout = false
      config.products_per_page = 20
    end
    ```

    Please see [Configuration](/developer/customization/configuration) section for more information.
  </Accordion>

  <Accordion title="Events and Subscribers">
    **Best for:** Reacting to model changes, syncing with external services, sending notifications, audit logging.

    <Info>
      Events are the **recommended way** to add behavior when something happens in Spree, replacing the need for decorator callbacks.
    </Info>

    Spree's event system lets you subscribe to events like `order.completed`, `product.updated`, `payment.paid`, etc.:

    ```ruby app/subscribers/my_app/order_completed_subscriber.rb theme={"theme":"night-owl"}
    module MyApp
      class OrderCompletedSubscriber < Spree::Subscriber
        subscribes_to 'order.completed'

        def handle(event)
          order = Spree::Order.find_by(id: event.payload['id'])
          return unless order

          # Sync to external service, send notification, etc.
          ExternalService.notify_order_placed(order)
        end
      end
    end
    ```

    **Key benefits:**

    * Loose coupling - your code doesn't depend on Spree internals
    * Async by default - keeps requests fast
    * Easier testing and upgrades

    Please see [Events](/developer/core-concepts/events) section for more information.
  </Accordion>

  <Accordion title="Webhooks">
    **Best for:** Notifying external services (ERPs, CRMs, fulfillment systems) when events occur.

    Webhooks send HTTP POST requests to external URLs when Spree events happen:

    * Order completed → Notify fulfillment system
    * Product updated → Sync with PIM
    * Customer created → Add to CRM

    Configure webhooks in **Admin > Developers > Webhooks** or via the API.

    Please see [Webhooks](/developer/core-concepts/webhooks) section for more information.
  </Accordion>

  <Accordion title="Dependencies">
    **Best for:** Swapping core services, serializers, and abilities with your own implementations.

    Spree allows you to replace core classes without modifying them:

    ```ruby config/initializers/spree.rb theme={"theme":"night-owl"}
    Spree::Dependencies.cart_add_item_service = "MyCartAddItemService"
    Spree::Dependencies.cart_remove_item_service = "MyCartRemoveItemService"
    ```

    This is cleaner than decorating services because you provide a complete replacement rather than patching behavior.

    Please see [Dependencies](dependencies) section for more information.
  </Accordion>

  <Accordion title="Admin Extensions">
    **Best for:** Adding menu items, form sections, dashboard widgets, and other UI elements to the admin panel.

    Spree provides declarative APIs for extending the admin without decorators or view overrides:

    **Navigation API** - Add menu items:

    ```ruby config/initializers/spree.rb theme={"theme":"night-owl"}
    Rails.application.config.after_initialize do
      Spree.admin.navigation.sidebar.add :brands,
        label: :brands,
        url: :admin_brands_path,
        icon: 'award',
        position: 35
    end
    ```

    **Partials API** - Add sections to forms:

    ```ruby config/initializers/spree.rb theme={"theme":"night-owl"}
    Spree.admin.partials.product_form << 'spree/admin/products/erp_section'
    ```

    Please see:

    * [Admin Navigation](/developer/admin/navigation) - For adding menu items
    * [Admin Partials](/developer/admin/extending-ui) - For extending UI
    * [Admin Tables](/developer/admin/tables) - For customizing list views
  </Accordion>

  <Accordion title="Search and Filtering">
    **Best for:** Making custom fields searchable/sortable in the admin and API.

    Instead of decorating models to add `ransackable_attributes`, use the Ransack configuration API:

    ```ruby config/initializers/spree.rb theme={"theme":"night-owl"}
    Spree.ransack.add_attribute :product, :erp_id
    Spree.ransack.add_association :product, :brand
    ```

    Please see [Search & Filtering](/developer/core-concepts/search-filtering#extending-ransackable-configuration) section for more information.
  </Accordion>

  <Accordion title="Authentication">
    **Best for:** Using your own user model or authentication system.

    Spree allows you to use your own authentication system instead of the default Devise-based one.

    You can find more information in the [Authentication](authentication) section.
  </Accordion>

  <Accordion title="Checkout flow">
    **Best for:** Customizing checkout steps and flow.

    With Spree you can change the checkout flow to fit your business needs - add steps, remove steps, or change the order.

    Please see [Checkout flow customization section](checkout) for more information.
  </Accordion>

  <Accordion title="Decorators">
    **Best for:** Adding associations, validations, scopes, and methods to Spree models. Use as a last resort.

    <Warning>
      Decorators should be used **only when no other option works**. They tightly couple your code to Spree internals and can break during upgrades.

      **Do NOT use decorators for:**

      * After-save callbacks → Use [Events](/developer/core-concepts/events) instead
      * External service sync → Use [Webhooks](/developer/core-concepts/webhooks) instead
      * Custom service logic → Use [Dependencies](dependencies) instead
      * Admin UI changes → Use [Admin Extensions](#admin-extensions) instead
    </Warning>

    Decorators are still appropriate for structural changes:

    ```ruby app/models/spree/product_decorator.rb theme={"theme":"night-owl"}
    module Spree
      module ProductDecorator
        def self.prepended(base)
          base.belongs_to :brand, class_name: 'MyApp::Brand', optional: true
          base.validates :external_id, presence: true
          base.scope :featured, -> { where(featured: true) }
        end

        def full_title
          "#{brand&.name} #{name}"
        end
      end

      Product.prepend(ProductDecorator)
    end
    ```

    Please see [Decorators](decorators) section for more information.
  </Accordion>
</AccordionGroup>
