Does Ruby on Rails Work With Lucia?

Partially CompatibleLast verified: 2026-02-20

Lucia can work with Rails, but it requires manual integration since Lucia is JavaScript-first and Rails has its own session management; you'll need to bridge the gap carefully.

Quick Facts

Compatibility
partial
Setup Difficulty
Moderate
Official Integration
No — community maintained
Confidence
medium
Minimum Versions
Ruby on Rails: 6.0
Lucia: 3.0

How Ruby on Rails Works With Lucia

Ruby on Rails and Lucia don't have native integration because Rails includes its own battle-tested session management (ActionDispatch::Session), while Lucia is primarily designed for JavaScript/TypeScript environments. However, you can use Lucia for API authentication when Rails serves as a backend API with a separate frontend (like Next.js or SvelteKit). In a monolithic Rails app, you're better off using Rails' built-in sessions or gems like Devise. If you're building a Rails API paired with a modern JavaScript frontend, you can configure Lucia on the frontend to manage sessions via secure HTTP-only cookies, with Rails validating session tokens in a middleware. The main friction point is that Rails' conventions around session management don't align with Lucia's lightweight, explicit approach. You'll end up writing custom middleware and session validation logic rather than leveraging Rails' conventions.

Best Use Cases

Rails backend API with a Next.js/SvelteKit frontend handling authentication via Lucia
Microservices architecture where Rails provides REST endpoints and Lucia manages frontend sessions independently
Progressive enhancement scenarios where a Rails monolith gradually adopts a decoupled JavaScript frontend
Multi-platform authentication where Lucia standardizes session handling across web and mobile frontends connecting to a Rails API

Rails API validating Lucia sessions

bash
gem install lucia-jwt
ruby
# config/initializers/lucia_auth.rb
class LuciaSessionMiddleware
  def initialize(app)
    @app = app
  end

  def call(env)
    request = Rack::Request.new(env)
    session_token = request.cookies['auth_session']
    
    if session_token
      # Validate token with your Lucia backend or decode JWT
      decoded = decode_lucia_token(session_token)
      if decoded && !token_expired?(decoded)
        env['lucia.user_id'] = decoded['user_id']
      end
    end
    
    @app.call(env)
  end

  private

  def decode_lucia_token(token)
    JWT.decode(token, ENV['LUCIA_SECRET'], algorithm: 'HS256')[0]
  rescue JWT::DecodeError
    nil
  end

  def token_expired?(decoded)
    Time.at(decoded['exp']) < Time.now
  end
end

# In your controller:
class ApiController < ApplicationController
  before_action :authenticate_lucia
  
  private
  
  def authenticate_lucia
    @current_user = User.find(env['lucia.user_id']) if env['lucia.user_id']
  end
end

Known Issues & Gotchas

critical

Rails session middleware will conflict with Lucia's session management if both are enabled

Fix: Disable ActionDispatch::Session in Rails config when using Lucia; configure your API to validate Lucia tokens instead

warning

CSRF protection in Rails doesn't automatically apply to Lucia-managed sessions

Fix: Implement token-based CSRF protection on your Rails API or rely on same-site cookies if your frontend is on the same domain

warning

Rails' session serialization (Marshal) won't work with Lucia's session format

Fix: Store session data in a custom database table or Redis that both Rails and your Lucia frontend can read

info

No built-in Rails helper methods for Lucia session management

Fix: Write custom authentication helpers or use JWT tokens instead of relying on Rails conventions

Alternatives

  • Rails + Devise: Rails-native authentication gem with built-in session management and conventions
  • Rails API + Auth0: Delegated authentication service, no session management needed in Rails
  • Node.js Express + Lucia: JavaScript monolith where Lucia is the native choice, simpler integration

Resources

Related Compatibility Guides

Explore more compatibility guides