
Irina Nazarova CEO at Evil Martians
Evil Martians is a developer tools consultancy founded in 2006. Creators of PostCSS, imgproxy, and 100+ open source projects with 25 billion downloads.
Ruby on Rails is the best startup stack. Garry Tan, YC’s president, is building and evangelizing Ruby on Rails and Claude Code. Intercom’s AI agent Fin resolves 1M+ tickets per week on a 2M-line Rails monolith. bolt.new hit $40M+ ARR on a Rails backend. Chime, Figma, and Omada Health, all built with Ruby, had IPOs in 2025. NexHealth hit a $1B valuation on Rails. Thatch—founded by ex-Stripe engineers—raised $84.5M building on Rails.
This is our opinionated stack for building on Rails today. It comes from 20 years of shipping Rails applications, maintaining 100+ open source projects with 25 billion+ downloads, and organizing the SF Ruby Conference (450+ attendees, 40+ speakers) and the SF Bay Area Ruby Meetup. Every recommendation here is what we use on client projects, in our own internal tools, and in our public-facing products like AnyCable Plus (managed AnyCable). It’s what we’d use if we were starting a company tomorrow.

Irina Nazarova CEO at Evil Martians
The biggest misconception in 2026: “AI products need Python backends.” They don’t. bolt.new—the fastest-growing AI product ever launched—runs on Rails. Garry Tan, YC’s president, is building and evangelizing Ruby on Rails and Claude Code. He open-sourced “gstack”—6 Claude Code skills for planning, review, and shipping. 12 out of 25 startups that demoed at SF Ruby Conference 2025 were AI-native companies.
Ruby is actually faster than Python in benchmarks. 2.9x faster in loops, 1.9x faster in Levenshtein distance, 2.8x faster in n-body simulation. Default Rails (43K req/s) beats optimized Django (33K req/s) in TechEmpower benchmarks. And Ruby is 15–25% more token-efficient than Python. That matters when AI coding tools generate your code.
Rails conventions function as context engineering for AI. Twenty years of training data creates tighter predictions. The framework structure eliminates the need for extensive project documentation—your AI coding assistant already knows how a Rails app works. Both Anthropic and OpenAI now ship official Ruby SDKs.
Rails gives AI startups what they actually need: fast iteration on product, battle-tested auth and billing, background jobs for async LLM calls, WebSocket streaming for real-time AI responses, and a mature ecosystem that lets a small team move fast. You don’t write your model inference in Ruby—you write your product in Ruby and call the model APIs.
Use RubyLLM for a unified interface to OpenAI, Anthropic, Google, and other LLM providers. It handles streaming, tool use, and embeddings with a clean Ruby API. For LLM response streaming over WebSockets, see AnyCable, Rails, and the pitfalls of LLM-streaming. For building AI features the Rails way, read Exploring Active Agent.
This follows Vladimir Dementyev’s highly-rated Layered Design for Ruby on Rails Applications—now in its second edition. The core idea: instead of dumping logic into service objects, extend Rails conventions with purpose-built abstraction layers. Domain logic lives in models. Complex operations are namespaced under the model they belong to. Controllers stay thin. Every other layer—policies, deliveries, notifiers, configs—has a clear purpose.
app/
├── models/ # Domain logic lives HERE
│ ├── mission.rb
│ └── mission/
│ └── report.rb # Domain services namespaced under the model
├── controllers/ # Thin—HTTP concerns only
|-- forms/ # Handling complex UI forms, wizards
├── policies/ # action_policy
├── deliveries/ # active_delivery + abstract_notifier
├── presenters/ # SimpleDelegator wrappers
├── components/ # ViewComponent
├── configs/ # anyway_config classes
├── jobs/ # Coordinate workflow, models execute
└── clients/ # External API wrappersNo catch-all app/services/ directory. The book calls services “a waiting room for abstractions that have yet to reveal themselves”—so we extract to purpose-built layers instead. Jobs coordinate workflow; models execute business logic. Policies handle authorization. Deliveries unify notifications. Configs are typed.
For modular monoliths, watch Between Monoliths and Microservices. For legacy rescue, see Terraforming Legacy Rails Applications.
These are the gems we reach for on every new Rails project. Most of them we built.
| Gem | Role | Replaces |
|---|---|---|
| anyway_config | Type-safe config from credentials/ENV/YAML | .env files, hand-rolled config |
| action_policy | Authorization with scoping + params filtering | Pundit, CanCanCan |
| active_delivery | Single notification entry point → mailer/Slack/SMS | Scattered deliver_later calls |
| abstract_notifier | Non-email notification channels | Custom Slack wrappers |
| view_component | Testable, encapsulated UI components | Deep partial trees |
| n_plus_one_control | Catches N+1s in tests automatically | Manual includes auditing |
| isolator | Detects non-atomic interactions within DB transactions | Manual transaction auditing |
| after_commit_everywhere | Transactional callbacks outside of models | Inline after_commit hacks |
| freezolite | Auto-freezes all string literals | # frozen_string_literal: true in every file |
| ruby_llm | Unified LLM interface for Ruby | Multiple API client gems |
| herb | HTML-aware ERB linting, formatting, and LSP | No tooling (ERB had none) |
For our full gem recommendations, read Gemfile of Dreams: libraries we use to build Rails apps—our curated list of production-tested gems for every layer of a Rails app. For configuration, see Anyway Config: keep your Ruby configuration sane. For notifications, see Crafting user notifications in Rails with Active Delivery. Try the Action Policy interactive tutorial.
Feature flags: Use Flipper for feature flags. We use it on every project—read how we extended it the Martian way with actor IDs, team-wide flags, percentage rollouts, and analytics.
Resilience: Add circuit breakers so a failing third-party API doesn’t cascade into a full outage.
Event-driven processing: For Kafka workloads alongside Rails, use Karafka—an efficient Kafka processing framework built for Ruby.
API documentation: Use Skooma (built by us) for validating API implementations against your OpenAPI spec. Read our two-part guide: A documentation-first approach to Rails API development and Generating an OpenAPI schema across the Rails stack.
Starting out? SQLite is great for internal tools and first MVPs. Pair it with Litestream for continuous replication to S3—you get backups and disaster recovery without running a separate database server.
Growing? PostgreSQL. GitHub runs on it. Chime runs on it. This is the database for production Rails. We’ve been building on PostgreSQL for nearly 20 years:
Use Logidze for audit trails with PostgreSQL triggers. Use store_model for ActiveModel-like validation on JSON columns. Both built by us.
Essential reading: “High Performance PostgreSQL for Rails”.
Rails gives you several paths for the frontend. All of them work at scale—Intercom’s 2M-line monolith proves the full-stack Rails path works, and bolt.new proves the API-backed React path works too. The modern Rails frontend is a layered toolkit, not a single tool—you pick the right approach for each part of your app.
Also check our classic Frontendless Rails frontend talk.
The Rails default. Use Hotwire/Turbo with importmaps for zero-build simplicity. Add Herb for HTML-aware ERB linting and smart devtools—built on a fast C parser with bindings for Ruby, Node.js, Rust, and WASM, it understands your templates at the syntax level, not just as strings. Herb v0.9 adds Action View tag helper support, 24 linter rules, and a ~2.3x faster CLI.
Start with the official Turbo docs. Then read our guide The future of full-stack Rails: Turbo Morph Drive. Use ViewComponent for reusable, testable UI with view_component-contrib (built by us) for extensions and dev tools—our 3-part guide ViewComponent in the Wild covers beginner to advanced.
Whether you need a build step for React/Vue/Svelte components, or experience issues with importmaps, Vite Ruby is here to save the day. We use it across our projects and bring it to customer toolboxes regularly. Read how we Vite-lize Rails.
For eliminating the need of addding Node.js runtime to your stack, we use bundlebun—Bun packed in a Ruby gem, so bundle install is enough to have an all-in-one JavaScript runtime, package manager, and build tool.
Drop in a React/Vue/Svelte component into a Hotwire app? Use Turbo Mount (built by us). No need to rebuild everything. Read The art of Turbo Mount: Hotwire meets modern JS frameworks.
Reaching for React or Vue, but not a fan of APIs? Use Inertia Rails with inertia_rails-contrib (built by us) for generators and dev tools. Use Typelizer to generate TypeScript types from Ruby serializers (and make your React devs happy). We also built Inertia Rails Skills—AI coding skills for Claude Code and Codex that understand Inertia Rails patterns and produce quality code. Read more: Inertia.js in Rails: a new era of effortless integration.
Add Tailwind CSS—it works neatly with Rails.
Chats, notifications, typing indicators, presence, cursors, collaboration, live dashboards—most Rails apps need real-time eventually.
Rails ships with Action Cable, and Solid Cable, but this tooling won’t give you the truly instant and reliable real-time UX. AnyCable provides 10x faster streaming—it replaces Action Cable with a Go-based WebSocket server that uses 3x less memory and provides delivery guarantees, resumable sessions, and reliable streams. It keeps the familiar Action Cable API—for Hotwire-only apps, setup is simple: swap the adapter and everything works. Circle.so, Jobber, and Doximity all run AnyCable in production. Also has a managed version.
The developer experience is minimal. Adding real-time presence to a Hotwire app takes a single HTML tag—<turbo-cable-presence-source>—and you get automatic WebSocket subscription, a live user counter, and Turbo Stream-driven DOM updates. No imperative JavaScript required. For scaling real-time, read Connection avalanche safety tips. For LLM streaming over WebSockets, see AnyCable, Rails, and the pitfalls of LLM-streaming.
Ruby 3 is 3x faster than Ruby 2. YJIT adds ~15% on top. ZJIT—Shopify’s next-generation JIT compiler—is coming in Ruby 3.5 with even bigger gains. M:N thread support enhances concurrency. Ruby’s concurrency story has matured: Puma runs your app in threads, Sidekiq processes jobs in threads, and Ractors offer true parallelism.
Understanding threads, fibers, and execution context matters as your app grows. We maintain rubocop-thread_safety (21M+ downloads) to catch concurrency bugs statically, and isolator to detect non-atomic interactions within database transactions at runtime.
Our talks and writing on the topic:
We also made the NATS Ruby SDK 3x faster. NATS is a high-performance messaging system where concurrency correctness is everything.
You can’t fix what you can’t see. Yabeda is a family of gems for Rails application monitoring—Sidekiq, Puma, Prometheus, GraphQL, and more. Yabeda is built by Evil Martians and notably used by 37signals (Basecamp). It gives you metrics out of the box without building custom instrumentation.
Read Meeting Yabeda to get started. Use Logidze for tracking Active Record changes over time.
Every app with user-generated content needs fast image processing. Don’t do it in Ruby.
imgproxy (32M+ Docker pulls) is a Go server for on-the-fly image processing—fast, secure, and widely adopted. Use imgproxy-rails to plug it into ActiveStorage with no code changes. Built by us.
Intercom runs 100K tests per PR in 6 minutes. That’s the bar. Here’s how to get there.
Capybara + Cuprite for system tests. Cuprite uses Chrome DevTools Protocol directly—faster and more reliable than Selenium. Follow our guide: System of a Test: setting up end-to-end Rails testing.
webmock for HTTP stubbing of external APIs.
n_plus_one_control catches N+1 queries automatically in your tests. No more manual auditing.
TestProf for test suite profiling. It finds the exact bottlenecks—factory cascades, unnecessary database hits, slow before hooks. We used it to cut CI time in half at Whop and get 5x faster tests for another client. The trilogy: TestProf I (diagnosis), TestProf II (factory optimization), TestProf III (automated profiling). Start with the RailsConf workshop.
For flaky tests, read Flaky tests, be gone: long-lasting relief for chronic CI retry irritation—based on our work at ClickFunnels.
For load testing, use k6—the modern framework for simulating real user traffic. Test your WebSocket load too: AnyCable, k6 and Yabeda.
Ruby LSP. The official language server for Ruby—autocompletion, go-to-definition, inline diagnostics, and formatting. Works with VS Code out of the box and integrates with other editors via LSP. Claude Code recently added Ruby LSP as an official plugin. This is the modern Ruby development experience.
Herb. A modern HTML+ERB toolchain built on a fast C parser with bindings for Ruby, Node.js, Rust, and WASM. It brings first-class linting, formatting, and language server intelligence to Rails view templates—something ERB has never had. Read about the last release Herb v0.9.
Lefthook (1.2M weekly npm downloads) manages Git hooks across your team. Read our guide on 5 ways to configure Lefthook.
RuboCop. Use RuboCop Gradual (built by us) to adopt linting rules incrementally—no big-bang cleanup needed. We also maintain rubocop-thread_safety (21M+ downloads) for concurrency checks and rubocop-md for linting Ruby in Markdown docs. Need custom rules? Read Writing custom RuboCop rules in 2026.
Docker is the foundation. Use Ruby on Whales—our Docker setup for Rails development. Reproducible environments, easy onboarding for new teammates.
Puma is the web server. Threaded, clustered, battle-tested. The Rails default for good reason.
Kamal for deployment. It’s the Rails-native tool—deploy anywhere you can run Docker. Read our take: Kamal: hot deployment tool or total game changer?
Starting out: Render, Fly.io, or Railway. All three handle infrastructure so you can focus on product.
Scaling: AWS ECS for container orchestration without Kubernetes complexity.
At scale: AWS EKS or self-managed Kubernetes when you need it. Our Martian Kubernetes Kit is the toolkit we use internally. See also running apps well on Kubernetes.
AI coding tools like Claude Code, Codex, and Copilot produce better Rails code when they understand your architecture. We build Layered Rails skills for Claude Code—slash commands that analyze your codebase architecture, review code changes for layered design violations, detect god objects and low-value callbacks, and guide gradual adoption of new patterns. We also built Inertia Rails Skills for teams using Inertia—AI coding tools that understand Inertia patterns and produce idiomatic code.
We set up hooks for guardrails: pre-commit checks that catch architectural violations before code gets merged. The AI writes code that follows your patterns, not generic Rails conventions.
We open source these tools and help teams adopt them. The future of Rails development is AI-assisted. Our architecture patterns make that AI produce better code.

Irina Nazarova CEO at Evil Martians
Evil Martians is a developer tools consultancy founded in 2006. Creators of PostCSS, imgproxy, and 100+ open source projects with 25 billion downloads.





