Roadie for Ruby HTML email transformation
Making HTML emails comfortable for the Ruby rockstars
At a glance
- What is it?
- Roadie is a Ruby library that inlines CSS and rewrites relative URLs in HTML emails. It suits Ruby applications that need email-ready markup, although it targets client behavior that remains inconsistent.
- Who is it for?
- Ruby applications should consider Roadie when their email templates need CSS inlining or absolute URLs without manually duplicating styles on every element. Projects that rely heavily on dynamic pseudo-classes, need verified rendering across specific clients, or cannot accept passive maintenance should resolve those concerns first.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 18 days ago.
- What is it written in?
- Mainly Ruby, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Roadie's purpose in Ruby email delivery
Roadie addresses a mismatch between ordinary browser HTML and the limited CSS support found in email clients. The README says some clients block downloadable stylesheets, while many email styles rely on a `<style>` element or a `<link>` element. The usual workaround is to copy declarations into each element's `style` attribute, but that approach is error prone and makes classes and reusable styling harder to maintain.
The gem is intended for Ruby developers producing HTML email bodies. It can process a complete HTML document through `Roadie::Document#transform` or a fragment through `#transform_partial`. That distinction matters for applications whose mailer views contain only a table or another small fragment. Roadie can add an HTML skeleton for full documents, while partial output remains partial.
This is a template transformation library, not a complete SMTP or email delivery service. Based on the documented API, an application constructs a document, supplies markup and styles, configures URL handling when necessary, and then uses the transformed result in its existing sending process. The repository metadata does not document an email provider, transport, queue, or campaign API.
CSS inlining and stylesheet discovery in Roadie
Roadie accepts CSS explicitly through `#add_css`, but it can also inspect the document's `<style>` and `<link>` elements. By default, those elements in the document head are processed and removed from the head after their applicable CSS is incorporated. A referenced stylesheet therefore becomes part of the transformed output rather than necessarily remaining as a separate downloadable resource.
For selectors that Nokogiri understands, Roadie assigns declarations to matching elements. The README states that selector order is handled carefully and that the result should behave similarly to a browser. It also documents two protections around existing declarations: `!important` rules are respected, and CSS does not overwrite styles already present in an element's `style` attribute. This makes Roadie useful when a template contains both shared stylesheet rules and deliberate one-off presentation.
Dynamic and otherwise uninlinable selectors take a different path. Rules involving selectors such as `:hover`, `:visited`, and `:focus`, along with constructs such as `@media`, are retained in a separate `<style>` element. The README explicitly warns that this changes specificity and may not work completely as expected. Roadie can expose the tradeoff through `keep_uninlinable_css`. Setting it to `false` skips CSS that cannot be inlined instead of retaining it.
Stylesheet discovery also has boundaries. A `media="print"` link or style is ignored, as is a `<style>` or `<link>` marked with `data-roadie-ignore`. Roadie removes the marker before it returns the final HTML. The marker controls stylesheet processing, but the README also defines an element-level meaning for URL rewriting, so its use should be chosen deliberately.
Absolute URLs and selective Roadie URL rewriting
Relative resources are unreliable in email because the recipient's mail client may not have the acceptance environment or application host as its base URL. Roadie addresses this by rewriting relative references when `url_options` define the target. Its documented configuration uses a host and protocol:
html = '... <a href="/about-us">Read more!</a> ...'
document = Roadie::Document.new html
document.url_options = {host: "myapp.com", protocol: "https"}
document.transform
# => "... <a href=\"https://myapp.com/about-us\">Read more!</a> ..."With that configuration, the README shows the relative `/about-us` link becoming `https://myapp.com/about-us`. Roadie applies this treatment to HTML link targets through `a[href]`, image sources through `img[src]`, and CSS declarations containing `url()`. Relative image paths and assets referenced from stylesheets can therefore share the same origin without relying on the recipient environment.
Individual elements can opt out with `data-roadie-ignore`. This is useful for links whose target is a placeholder populated later by the mail delivery system:
<a href="|UNSUBSCRIBE_URL|" data-roadie-ignore>Unsubscribe</a>Roadie will still inline CSS on that element, but it leaves the URL unchanged and removes the marker from the output. The repository does not document automatic handling for a generic set of delivery-provider placeholders, so applications should mark the specific elements that require preservation.
Installing Roadie and transforming the first template
The README instructs users to add the gem through RubyGems and run Bundler. The documented dependency declaration is:
gem 'roadie', '~> 5.2'After adding it to the Gemfile, Bundler installs the declared dependencies:
bundle installThe first transformation can begin with a full HTML document. This adds CSS at runtime and then transforms the complete document:
document = Roadie::Document.new "<html><body></body></html>"
document.add_css "body { color: green; }"
document.transform
# => "<html><body style=\"color:green;\"></body></html>"The README shows the result as `<html><body style="color:green;"></body></html>`. The selected `body` rule is moved into the element's `style` attribute.
For an email view that is intentionally a fragment, use the partial entry point instead:
document = Roadie::Document.new "<div>Hello world!</div>"
document.add_css "div { color: green; }"
document.transform_partial
# => "<div style=\"color:green;\">Hello world!</div>"The documented output is `<div style="color:green;">Hello world!</div>`, without an added document layout. During adoption, the useful first check is not merely whether the command completes. Inspect the returned HTML and confirm that the expected inline style is present, ignored markers have been removed, and required resource URLs have the intended origin.
Asset providers, callbacks and media-query ordering
Roadie has runtime hooks for template pipelines beyond simple CSS strings. The `asset_providers` option supplies objects invoked when a document references a CSS file. `external_asset_providers` serves a different case: absolute CSS URLs. The README notes that an externally referenced stylesheet is inlined only when an external provider is configured; otherwise it is ignored. This distinction prevents the library from implicitly fetching every absolute stylesheet, but it also means an application must configure the correct provider for externally hosted CSS.
Two callbacks provide explicit transformation boundaries. `before_transformation` runs before processing, while `after_transformation` runs after completion. Their presence allows an application to prepare or inspect state around Roadie, although the README does not describe their signatures or guarantee more specific behavior. `serialization_options` is passed to Nokogiri as an integer bitmap. Its default is `Nokogiri::XML::Node::SaveOptions::NO_DECLARATION | Nokogiri::XML::Node::SaveOptions::NO_EMPTY_TAGS`, which controls the serialized HTML form.
Media-query behavior is configurable through `merge_media_queries`. By default, the option groups compatible media-query rules. The README shows separate 600px and 400px blocks being consolidated, with the two 600px blocks merged. This can reorder declarations. If preserving the source ordering within media queries matters to a template, set `merge_media_queries` to `false`. That setting makes the tradeoff explicit instead of assuming that grouped CSS is always equivalent.
Roadie limitations, alternatives and maintenance implications
The clearest limitation is dynamic CSS. Roadie retains selectors and rules that cannot be represented as ordinary inline declarations, but the README warns that their changed specificity can prevent the expected result. Email clients also differ in how they interpret CSS, and the README does not claim rendering verification against a particular client matrix. Roadie reduces template conversion work, but it does not make unsupported client features universally dependable.
For a different approach, a hand-authored email template can place all visual declarations directly in `style` attributes and use fully absolute URLs from the start. That avoids a runtime stylesheet transformation layer, but every template must remain synchronized manually and shared styling becomes difficult to reuse. Roadie instead accepts class-based CSS and performs the conversion during processing. This is the meaningful difference: manual email markup controls each declaration at authoring time, whereas Roadie centralizes conversion in a Ruby document pipeline.
The repository is not archived, and its last push was on 2026-10-04, indicating recent repository activity for this review. However, the README explicitly places the gem in passive maintenance mode. Passive maintenance means new feature work should not be assumed. The repository has no GitHub releases, so the changelog and dependency compatibility are more relevant than a release cadence when selecting a version. The README's `~> 5.2` constraint should be checked against the application's Ruby and gem resolution rather than treated as an open-ended upgrade path.
Roadie uses the MIT license. That is favorable for inspecting, modifying and distributing the software under the license's stated terms, but it does not answer project-specific questions about email assets, client rendering, or application dependencies.
Editorial conclusion
Ruby applications should consider Roadie when their email templates need CSS inlining or absolute URLs without manually duplicating styles on every element. Projects that rely heavily on dynamic pseudo-classes, need verified rendering across specific clients, or cannot accept passive maintenance should resolve those concerns first. The initial adoption check should confirm that Roadie 5.2 remains compatible with the application bundle, then inspect transformed output for required selectors, links and images.
Frequently asked questions
How do I install Roadie in a Ruby project?
Add `gem 'roadie', '~> 5.2'` to the Gemfile and run `bundle install`. The repository has no GitHub releases, so the documented Gemfile constraint is the available version guidance.
How does Roadie handle a partial HTML email template?
Use `Roadie::Document#transform_partial` for markup such as a `<div>` fragment. The README shows that the method applies CSS without adding a full HTML skeleton.
How can Roadie preserve a link URL that should not be rewritten?
Add `data-roadie-ignore` to the element. Roadie will leave its URL unchanged, can still apply inline CSS, and removes the marker before returning the transformed HTML.
What happens to hover rules and media queries in Roadie?
Dynamic selectors and constructs such as `@media` are retained in a separate `<style>` element. The README warns that specificity changes may make these rules behave differently from inline CSS.
Can Roadie transform externally referenced CSS files?
Yes, when `external_asset_providers` is configured for absolute CSS URLs. The README says that otherwise external stylesheets are ignored rather than fetched automatically.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/mange-roadie)Was this useful?