Does Ruby on Rails Work With Payload CMS?

Partially CompatibleLast verified: 2026-02-26

Rails and Payload CMS can work together as a headless setup, but they're fundamentally misaligned architectures—Rails wants to be your full stack while Payload is TypeScript-first.

Quick Facts

Compatibility
partial
Setup Difficulty
Moderate
Official Integration
No — community maintained
Confidence
high
Minimum Versions
Ruby on Rails: 6.0
Payload CMS: 1.0

How Ruby on Rails Works With Payload CMS

Rails and Payload CMS integrate via REST/GraphQL APIs rather than native coupling. Your Rails app acts as a separate client consuming Payload's headless APIs to fetch content, while Payload runs as an independent Node.js/TypeScript application. This works well for content distribution but creates operational overhead—you're managing two separate applications with different ecosystems, deployment targets, and monitoring requirements.

The developer experience is straightforward: use Rails' built-in HTTP clients (Net::HTTP, HTTParty, or Faraday) to query Payload's REST or GraphQL endpoints, cache responses with Rails.cache, and render content in your views. However, you lose Rails' convention-over-configuration benefits since content schema lives entirely in Payload's TypeScript codebase. Developers must context-switch between Ruby and TypeScript, and debugging content-related issues requires understanding both systems.

This pairing works best when Payload handles complex content workflows (permissions, versioning, localization) that would be tedious to build in Rails, while Rails focuses on business logic and custom features. The architectural separation provides flexibility—you can swap frontends or add mobile apps consuming the same Payload instance—but introduces API latency, cache invalidation complexity, and increased deployment complexity.

Best Use Cases

Multi-channel publishing: Rails web app, mobile app, and static site all consuming from single Payload CMS instance
Complex editorial workflows: Payload handles versioning and approval chains while Rails implements custom commerce or membership logic
Content-heavy Rails app: Migrating from Rails-based content management to Payload to improve content editor experience
Microservices architecture: Payload as dedicated content service with Rails as separate business logic service

Rails fetching content from Payload CMS

bash
bundle add httparty
ruby
# app/services/payload_client.rb
class PayloadClient
  include HTTParty
  base_uri ENV['PAYLOAD_URL'] || 'http://localhost:3000'
  default_timeout 5

  def self.fetch_pages
    response = get('/api/pages', {
      query: { limit: 100 },
      headers: { 'Authorization' => "Bearer #{ENV['PAYLOAD_API_KEY']}" }
    })
    response['docs']
  end

  def self.fetch_page(slug)
    pages = fetch_pages
    pages.find { |p| p['slug'] == slug }
  end
end

# app/controllers/pages_controller.rb
class PagesController < ApplicationController
  def show
    @page = Rails.cache.fetch("payload_page_#{params[:slug]}", expires_in: 1.hour) do
      PayloadClient.fetch_page(params[:slug])
    end
    render :show
  end
end

Known Issues & Gotchas

warning

API latency in page renders: Each view request may trigger multiple Payload API calls, causing slow initial loads without proper caching

Fix: Implement aggressive HTTP caching with ETags, use Rails.cache for API responses, or pre-fetch content at deployment time

warning

TypeScript-first Payload means content schema changes require redeploying Payload, not just Rails—no Rails migrations parity

Fix: Treat Payload as immutable infrastructure; use feature flags in Rails to handle schema transitions gracefully

warning

Authentication mismatch: Payload has its own user/permission system separate from Rails auth, creating dual login management

Fix: Use Payload's API key authentication for Rails, implement separate admin auth in Payload, or build JWT bridging logic

info

Local development complexity: Running Payload and Rails simultaneously requires Docker Compose or manual process management

Fix: Use docker-compose.yml or dev containers to orchestrate both services locally

Alternatives

  • Next.js + Payload CMS: Both TypeScript-based, native integration, better DX but requires learning JavaScript for backend logic
  • Rails + Strapi: Strapi is Node/JavaScript but simpler than Payload, lighter weight alternative for Rails integration
  • Rails + Contentful: Mature headless CMS with better Rails ecosystem support and official gems, but less extensible than Payload

Resources

Related Compatibility Guides

Explore more compatibility guides