erbfmt v0.2.0
erbfmt v2.0.0
erbfmt v2.0.0 is a major update since v1.0.0, focused on making ERB formatting safer, easier to run across Rails projects, and more practical to use from editors and CI.
Highlights
- Added recursive directory input support, so commands like
erbfmt --write app/viewsnow discover matching ERB files without requiring a shell glob. - Improved multi-file execution. A parse error in one file no longer stops the entire run; erbfmt reports the failure and continues processing the remaining files.
- Improved formatting for long ERB helper calls, including common Rails patterns such as
render,link_to,form_with,image_tag, andvideo_tag. - Improved wrapping for long HTML tags and attributes, including attributes that contain ERB.
- Added safer formatting behavior for inline-sensitive HTML and ERB patterns, reducing the chance of visual regressions caused by inserted newlines.
- Improved lint diagnostics with source excerpts and clearer locations.
- Expanded configuration support, including
files.includesfor selecting and excluding files. - Improved VS Code integration, including formatting, diagnostics, syntax highlighting for
html-erb, comment toggling, and command-based CLI execution such asbundle exec erbfmt. - Improved RubyGems distribution and documentation for Bundler-based Rails projects.
Formatter
This release improves formatting for real-world Rails view code. Long helper calls can now be wrapped into a more readable multi-line form:
<%=
render(
partial: "profile",
locals: {
current_user: current_user,
account: account,
selected_status: selected_status
}
)
%>Long HTML tags are also easier to read:
<section
class="profile-card profile-card--featured"
data-controller="profile-card autosave"
data-profile-card-user-id-value="<%= user.id %>"
aria-labelledby="profile-heading"
>The formatter also takes a more conservative approach around whitespace-sensitive and inline-sensitive content. Patterns such as adjacent inline ERB output, inline elements next to text, pre, textarea, script, style, svg, math, and contenteditable are handled more carefully to avoid changing rendered output.
CLI
Directories can now be passed directly:
erbfmt --write app/views
erbfmt --check app/views
erbfmt --lint app/viewsWhen multiple files are processed, erbfmt now continues after file-level parse errors and reports all failures at the end. This makes directory-based formatting and CI checks much more useful on larger Rails applications.
Linter
Lint output is now easier to read, with source excerpts and precise line/column information:
app/views/users/show.html.erb:
error: duplicate HTML attribute `class`
--> line 1, column 32
|
1 | <article class="card" id="one" class="wide"></article>
| ^
The linter also includes additional HTML and ERB checks, including duplicate attributes, invalid HTML nesting, deprecated tags, self-closing HTML tags, empty ERB tags, and unsupported ERB control-flow.
Configuration
erbfmt.json now supports file include and exclude patterns:
{
"files": {
"includes": [
"app/views/**/*.html.erb",
"!app/views/generated/**"
]
}
}This makes it easier to run erbfmt at the project root while excluding generated or intentionally unmanaged templates.
Editor Integration
The VS Code extension now provides a more complete editing experience for .html.erb files:
html-erblanguage support- syntax highlighting
- document formatting
- diagnostics
- ERB-aware comment toggling
- support for CLI commands such as
bundle exec erbfmt
The extension still delegates formatting and linting to the erbfmt CLI, so editor, terminal, and CI behavior stay consistent.
Installation
For Rails projects, Bundler is the recommended installation path:
bundle add erbfmt --group development --require false
bundle exec erbfmt --versionFor a global install:
gem install erbfmt
erbfmt --versionNotes
erbfmt is still conservative by design. It does not try to fully parse Ruby as a Ruby AST, and it may preserve complex or ambiguous Ruby expressions instead of rewriting them. The formatter prioritizes avoiding visual changes in rendered HTML over aggressively reflowing every possible expression.