This article was first published on Rails Designer
I am excited to introduce Perron, an OSS Rails-based static site generator (SSG). This one has been in the making for years. Not that the actual building took years—it was just a few hours every week over a few months—but conceptually I have been thinking about this for a long time.
Want to check it out right away? Check out and ⭐ the repo or explore the docs. 👈
So another static site generator? In 2025? While there are already hundreds (thousands?) of similar tools out there? Why?!
Good question! For one, because I can. 🤷 But more importantly all of the existing (great!) SSG, including those written in Ruby, do not match the framework I built my products in, which happens to be Rails. After more than a decade, I still enjoy building my (and other's) profitable products in it. I know where things live, I know its shortcomings, how to best approach certain features and I have my list of gems I love to use. From the Tailwind CSS gem, to the ViewComponent and so on.
But once I need to build the static (marketing) site for my product, all of that info is useless. Whatever SSG you choose, you need to learn its best practices, find where things live and learn new paradigms.
That is a time-sink. Even if you defaulted to a SSG (even a Ruby-based one!), there is the mental overhead of switching between them. If you are solo (or part of a small team), that is costly time. I think Perron is a solution to that.
Before continuing (especially if you are an English-native speaker 😬): what does Perron mean? It is Dutch/French meaning: a platform at a railway station from where passengers can board or disembark trains. Choo-choo! 🚂
How does Perron work?
Just like your rails app does! You develop it while running rails server
or, more commonly, bin/dev
. Isn't that beautiful?
Routes looks like this:
Rails.application.routes.draw do
resources :articles, module: :content, only: %w[index show]
resources :pages, module: :content, only: %w[show]
root to: "content/pages#root"
end
And the articles controller, for example, like this:
class Content::ArticlesController < ApplicationController
def index
@resources = Content::Article.all
end
def show
@resource = Content::Article.find(params[:id])
end
end
How about a layout file?
<!DOCTYPE html>
<html class="scroll-smooth">
<%= render "shared/head" %>
<body>
<%= yield %>
</body>
</html>
That… looks… just like Rails? 🤔 Correct. Even better: it is Rails! Perron uses all the goodies from Rails.
Features of Perron, a.k.a. what makes Perron worth giving a try
The short answer as to why you should give Perron a try is because you can develop your site in Rails, while publishing a fully static site by running bin/rails perron:build
. All ready to deploy on your favorite platform: Netlify, S3 or DigitalOcean. See the docs about deploying to production.
Perron is a light-weight gem that you add to your Rails app. It then gives you many features to make building typical SaaS/marketing sites (and any content site really) easier and, dare I say, a joy? 🛝 It uses many of the common best-practices of existing SSG out there.
Perron uses the concept of resources (a class that inherits from Perron::Resource
). You can create a new one by running: bin/rails generate content Post
. This will create the following files:
-
app/models/content/post.rb
; -
app/controllers/content/posts_controller.rb
; -
app/views/content/posts/index.html.erb
; -
app/views/content/posts/show.html.erb
.
Looks familiar too, right?
And what would this class look like? Something like this maybe:
class Content::Post < Perron::Resource
CATEGORIES = {
hotwire: "Hotwire",
tailwindcss: "Tailwind CSS",
rails: "Ruby on Rails"
}.with_indifferent_access
delegate :category, :title, :description, to: :metadata
validates :title, :description, presence: true
validates :category, inclusion: { in: CATEGORIES.keys }
end
Yes, you see that right. You can use the typical (ActiveModel) validations too! 🤓 Perron gives you bin/rails perron:validate
to check if all validations pass for your resources.
Notice metadata
above? It is a method on Perron::Resource
that outputs all resource's frontmatter, defined as yaml at the top of your markdown content. See the frontmatter and metatags docs for more details.
And indeed, markdown of course is supported. ❤️ Perron offers a markdownify
helper, but doesn't force you to use a specific parser. You can bundle add
one yourself (either commonmarker
, kramdown
or redcarpet
). And it will just work ™.
Talking about markdown. Perron can transform the HTML content for you. For example add target=_blank
to all links, loading=lazy
to all images or create your own processor to do whatever you need (example add a copy button to all code blocks). You can learn more about markdown and html transformations in the docs.
What other features does Perron give me?
I have built Perron with typical SaaS/marketing sites in mind. So a feature like scheduling content, working with structured data (think author or employee data), but also support for RSS/JSON feeds and XML sitemap are all included out-of-the-box.
Collection of snippets, component and templates
Besides all of this, I have built a small collection of snippets, UI components and templates. It uses Rails' application templates for this (another reason why I wanted it to be a Rails-based gem). For example: start a Perron-powered site, a table of content component or configuration to deploy to Netlify.
That's the gist of it. There is quite more packed in Perron. And there is more to be added in the future as well. From new features, to bugfixes and snippets, templates and marketing site-specific UI components.
I would love if you could star it on GitHub and then give it a try. If you want to learn more, see the docs site. 👈
Top comments (1)
What features or improvements are truly missing from Perron right now?