Ships with Rails 8.2
One language and toolchain that understands your HTML and Ruby together.
Lint · Format · Analyze · Render · Tooling
herb-lint app/views/users/show.html.erb
[warning] Prefer `image_tag` helper over manual `<img>` with dynamic ERB expressions. (erb-prefer-image-tag-helper)
app/views/users/show.html.erb:2:7
1 │ <div class="avatar"> → 2 │ <img src="<%= user.avatar_url %>"> │ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 3 │ </div>
[1/2]
[warning] Missing required `alt` attribute on `<img>` tag. (html-img-require-alt)
Summary: Checked 1 file Offenses 2 warnings Rules 146 enabled | 22 not enabled Duration 34ms
The same files you have now, understood properly for the first time.
168 rules covering accessibility, HTML correctness, Action View usage and security, with 146 on by default. Run them in your editor, on commit, or in CI.
$ herb-lint Rule offenses: a11y-avoid-generic-link-text (14 offenses in 9 files) actionview-no-implicit-partial (6 offenses in 4 files) html-img-require-alt (3 offenses in 3 files) Summary: Checked 144 files Offenses 23 warnings Fixable 9 offenses
Indentation, line wrapping and attribute layout that respect both the HTML tree and the ERB inside it. Nothing gets reflowed into the wrong branch.
before <div class="card" id="u"><%= u.name %></div> after <div class="card" id="u"> <%= u.name %> </div>
Hover, go to definition, diagnostics and code actions for HTML+ERB. Works in VS Code, Zed, Neovim and anything else that speaks LSP.
<%= render "users/card", user: user %> └─ app/views/users/_card.html.erb strict locals: user: required compact: = false
app/views/users/show.html.erb
<h1>Hello, <%= @user.name %></h1> <% if @user.admin? %> <span class="badge">Admin</span> <% end %>
That is Herb. Your existing .html.erb templates are already valid Herb templates, so there is nothing to rename and no new syntax to learn.
There is nothing to learn.
You already know Herb.
Everything below is built on the same parser, so the linter, the formatter, your editor and the renderer all share one foundation.
Development and CI
Wherever you call them
Herb ships inside tools you already use, so there is a good chance you are already running it without having it installed explicitly.
Herb::Engine is the default for HTML-format templates. Your .html.erb views render through Herb with nothing configured, and other formats such as .json.erb fall back to Erubi.
Ships a Herb template registered for .herb and .html.erb. Tilt is the template interface behind Sinatra, Roda and Hanami's view layer, so Herb is available there with no wiring of your own.
The Herb Language Server comes pre-installed with Zed's official Ruby extension. Install the Ruby extension and it is there.
Want to take your templates further and build dynamic interfaces without a JavaScript framework? ReActionView makes your existing HTML+ERB templates reactive, with fine-grained updates down to a single value, attribute or row, and no new syntax or build step.
Herb is an independent open source project, and it relies on the companies that use it to keep going. If your team depends on Herb, consider sponsoring the project.
Companies
People
Herb is created and led by Marco Roth, with help from its contributors.
Grant 2026 Gem Fellow. Herb was one of eight projects selected for the 2026 Gem Fellowship, a grant partnership between gem.coop and Contributed Systems, the company behind Sidekiq. It funded stabilization work toward 1.0 and the groundwork for reactive rendering. Read the final report →
Nothing to add to your Gemfile. This parses every template in the project and reports what it finds.
$ gem exec herb analyze