Rails as an HTML container
  • I started working with Rails 13 years ago (v 3.0), and have used it almost exclusively since then. In that time, I've easily worked on 50+ codebases in some form or another, and seen every library and pattern under the sun on small and large teams. What's remarkable is that, while Rails itself has changed a lot in that time (we're now at v 7), the underlying fundamentals of the web have changed remarkably little, and the approach I now follow for building apps with Rails would have been completely possible with the first version of Rails I learned, way back in 2010.

  • The crux of my approach is this: Web apps are built around HTML. Browsers are extremely good at fetching and displaying HTML - so that part is taken care of for us. Additionally, relational databases have been around for a very long time and do their job - storing and retrieving data - very well.

  • So without Rails, as programmers we already have out-of-the-box solutions for storing data, and for delivering HTML. What we don't have is a way to combine them both - to hydrate the HTML with specific data based on what user is requesting it.

  • HTML: the eighth wonder of the world

  • As demand for programmers seems to continuously exceed the supply, it's generally believed that in order to be a coder, one must be Very Smart™ . And yet HTML - the bedrock around which all of this software is built - is actually very approachable and easy to learn: So much so that children and adults can understand and learn the basics in a day. This is a remarkable fact.

  • As someone who's spent a lot of time dealing with the pain of finding and hiring software engineers, I've thought a lot about why it's so difficult. The result of that thinking can be boiled down to the following bullet points;

    • Holding that the only necessary complexity to building web software - beyond knowing How HTML Works and How Databases Work - is knowing how to hydrate html with the contents of a database, we can infer that the rest of the complexity is incidental complexity.

    • Most of the incidental complexity comes from 1. Tooling, and 2. Framework-specific concepts.

    • As a result, when hiring developers, the primary thing we're evaluating is their existing technical knowledge.

  • What if we think of Rails not as "Rails is a large framework for building complex web apps, whose libraries and patterns (hotwire, stimulus, turbo...) need to be studied", to "Rails is a way to access a collection of utilities that make it easier to work with HTML"

  • At this point I've worked with dozens of people using this approach, who had little to no prior rails experience, who were able to understand non-starter codebases after just a few hours. One exercise that helped was drafting up a cheat sheet with some of the most common code snippets. For people who have some web experience but no Rails experience, simply reading through this is a psychological-barrier-lowering exercise.


  • Rails (as an HTML Container) Cheat Sheet

  • A simple way to specify routes

  • # config/routes.rb
    Rails.application.routes.draw do
      get "/info" => "site#info", :as => "info"
    end
  • <a href="<%= info_path %>">Build</a>
  • A simple way to handle identity

  • gem 'devise'
  • before_action :authorize_user!
  • if user_signed_in?
      do_something
    end
  • A set of simple helpers for building html templates

  • <div id="menu">
      <%= render :partial => "common/menu" %>
    </div>
  • A simple, secure way to work with a database

  • user = User.new
    user.first_name = "Tony"
    user.save
    user.valid?
    user.errors.full_messages
  • people = User.where("location = ?","ireland").page(3)
  • <%- @people.each do |person| %>
      <h1><%= person.first_name %></h1>
      <img src="<%= person.image.url %>"></img>
    <% end %>
  • A simple way to access and use data submitted by forms

  • params[:first_name]
  • The above code snippets cover a surprisingly large amount of the code that's needed to build simple software.


  • Further Implications

  • With the baseline approach of "Let's center html and minimise the learning curve of everything else", we also landed on a few more somewhat surprising conclusions. They became so long that we moved them into a separate post - Friendly Rails guidelines


  • Common Objections

  • Why go to all this trouble? Can't you just hire more experienced devs?

  • See my opinions on the very real and very painful developer hiring problem.

  • Ok so you made the codebase easier to work with. There's still a huge learning curve for the tooling and infrastructure

  • See our adventures in Remote Development, which totally remove a whole class of environment and infrastructure setup issues.

  • You said you don't use pre or post compilation, but you do use Tailwind. How is that so?

  • We created static-tailwind, which includes most of the utility with none of the compilation. There is a performance implication, so it doesn't work in all cases, but in most the hit is unnoticeable.

  • But the markup hurts my eyes

  • I feel you. If that's more important for you, then don't follow the advice in this article.

    • Ok, but your apps are going to feel slow and crappy

    • This isn't just Rails

    • Remote Form Behaviour

    • Prefer HTMX over Turbolinks and Turbo forms


    • Website Page

    • Covered By✅ Browser✅ Browser + CSS + Js✅ Relational Database❌
      Task
      Fetch and deliver HTML
      Decorate HTML (styling and interactions)
      Store Data
      Hydrate HTML with user data