CLI tool
rouge-ruby/rouge avatar
rouge-ruby/rouge

Rouge: a pure Ruby syntax highlighter that speaks Pygments CSS

A pure Ruby code highlighter that is compatible with Pygments

3,452 stars815 forksRubyNOASSERTION

At a glance

What is it?
Rouge is a Ruby gem, Jekyll's default highlighter, and a CLI called rougify. It solves one problem well: turning source code into tokenized HTML or ANSI text without a Python dependency, at the cost of Pygments' breadth and a few rough edges in theme handling.
Who is it for?
Adopt Rouge if you are already in Ruby or Jekyll and want highlighting with no Python or native extension in the stack; the gem installs with one line and rougify covers terminal and CSS generation. Do not adopt it if you need Pygments' full language list, its exact token stream, or a theme ecosystem larger than the built-in set, because Rouge's compatibility promise is about HTML output and stylesheets, not about being a drop-in Pygments replacement at the lexer level.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 8 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 September 26, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem Rouge solves, and who actually needs it

Highlighting source code in a web page or a terminal usually means one of two things: shelling out to Pygments, or pulling in a JavaScript highlighter that runs in the browser. Rouge takes the third path. It is a pure Ruby syntax highlighter, so it runs wherever Ruby runs, with no Python interpreter and no native extension to compile. The README states it can highlight over 200 different languages and output HTML or ANSI 256-color text, and that its HTML output is compatible with stylesheets designed for Pygments.

That last sentence is the whole pitch. If you have an existing Pygments CSS file, Rouge will emit markup that the same classes style. The people who benefit most are Ruby web developers, static site authors, and anyone maintaining a Jekyll site, since Rouge is Jekyll's default syntax highlighter and is used out of the box for text wrapped in the {% highlight %} template tags. If your stack is not Ruby and you are not generating HTML or terminal output, Rouge is solving a problem you do not have.

How Rouge tokenizes and formats: lexers, formatters, themes

Rouge splits the job into three objects that you wire together yourself. A lexer turns source text into an Enumerable of token and value pairs. A formatter consumes that stream and yields strings. A theme supplies the styling. The README's library example makes the pipeline explicit: it reads a file, builds Rouge::Formatters::HTML.new, builds Rouge::Lexers::Shell.new, and calls formatter.format(lexer.lex(source)). Nothing is implicit.

The formatter layer is where most of the design decisions live. Rouge::Formatters::HTML emits standard class names for tokens with no div wrapping. HTMLInline.new(theme) inlines styling into style attributes for email and other environments with weak CSS support. HTMLLinewise, HTMLLineHighlighter, HTMLLineTable, and HTMLTable all split output per line with different trade-offs: HTMLLineTable gives each line its own table row, while HTMLTable keeps a single table row, which the README notes is more DOM-friendly for JavaScript scripting but breaks column alignment on long lines. HTMLPygments wraps another formatter in the div structure that Pygments stylesheets expect. Terminal256 and TerminalTruecolor cover the terminal, and Tex wraps each token in an \RG{toktype}{text} tag.

The README is direct about the intended extension path: for custom presentation, write your own formatter rather than patching output. Subclass Rouge::Formatter, define a tag, and implement #stream(tokens, &block). The base class provides #token_lines(stream, &block) to split tokens into lines, and the HTML formatter provides #span(token, value). If you need different span markup, override #safe_span(token, safe_value), which receives the token type and pre-escaped content. That is a small surface area, and it is the reason the formatter list can stay short.

Installing Rouge and highlighting a file with rougify

The README gives two install paths. Add the gem to your Gemfile, or install it directly from the command line:

bash
gem install rouge

Once installed, the rougify command highlights files in the terminal. The README shows three forms: plain highlighting of a file, selecting a theme, and exporting a stylesheet.

console
$ rougify foo.rb
$ rougify foo.rb -t monokai.sublime
$ rougify style monokai.sublime > syntax.css

The first command prints foo.rb with ANSI colors using the default theme. The second switches to the monokai.sublime theme. The third does not highlight anything; it writes the CSS rules for that theme to syntax.css, which is what you would link from a page that uses Rouge's HTML output. If you are generating TeX instead, the README notes that rougify style mystyle --tex produces definitions for the \RG tags and the surrounding environment.

As a library, the README's example reads a file, lexes it, and formats it, then renders a theme with a scope so the generated CSS only applies inside a container:

ruby
require 'rouge'

source = File.read('/etc/bashrc')
formatter = Rouge::Formatters::HTML.new
lexer = Rouge::Lexers::Shell.new
formatter.format(lexer.lex(source))

Rouge::Themes::Base16.mode(:light).render(scope: '.highlight')
Rouge::Theme.find('base16.light').render(scope: '.highlight')

The two theme lines are alternatives, not a sequence. The first builds a Base16 theme in light mode directly; the second looks the same theme up by string through Rouge::Theme.find.

Where Rouge is the wrong tool

The compatibility claim in the README is narrower than it first sounds. Rouge's HTML output is compatible with Pygments stylesheets, which means the class names line up. It does not mean Rouge's lexers produce the same tokens as Pygments for every language, and the README makes no such claim. If you depend on a specific token classification that Pygments emits, or you use a Pygments lexer for a language Rouge has no lexer for, switching to Rouge is a rewrite of your expectations, not a swap of a dependency.

The formatter defaults are also a trap for anyone migrating from Rouge 1.x. HTMLLegacy exists precisely because the 1.x options changed, and it carries inline_theme, line_numbers, wrap, and css_class as backwards-compatibility switches. New code should not start there. And HTMLTable's single-row design, which the README describes as more DOM-friendly, has a documented cost: long code lines mess with the column alignment. If your code samples contain long lines and you need a gutter that stays aligned, HTMLLineTable is the formatter to look at instead.

Finally, the README does not document theme fallback behaviour when Rouge::Theme.find is given a name that does not exist. Treat theme names as something to verify rather than assume.

Rouge versus Pygments and the JavaScript highlighters

The obvious alternative is Pygments itself. Pygments is the reference implementation for this kind of highlighting, and Rouge's README treats it as the compatibility target rather than a rival. The difference in approach is the runtime: Pygments is Python, so a Ruby application that uses it needs a Python process, a bridge, or a build step. Rouge is pure Ruby, so it loads in the same process as the application. You trade Pygments' language coverage and its exact token output for that. For a Jekyll site, the trade is already made for you, because Rouge is the default and there is nothing to configure.

The other family is client-side highlighters written in JavaScript, which move the work to the browser. Rouge does the opposite: highlighting happens when the page or asset is generated, so the browser receives finished markup and styled classes. That is the right shape for static sites and for anything that must work without JavaScript. It is the wrong shape if your code samples are produced dynamically in the browser after load, because Rouge cannot run there.

Within Rouge itself, the meaningful choice is between the built-in formatters, not between Rouge and something else. HTML with an external stylesheet is the default and the most cacheable. HTMLInline is for email and CSS-poor environments. Terminal256 and TerminalTruecolor are for command line output, with truecolor avoiding the 256-color approximation. Those are not competitors; they are the same lexer with different output contracts.

Maintenance, upgrades, and the licence question

The repository is not archived, and the last push was on 2026-09-22. Recent releases are v5.1.0 on 2026-08-06, v5.0.0 on 2026-05-27, and v4.7.0 on 2025-12-31. The jump from 4.7.0 to 5.0.0 is the upgrade event worth planning for, and the CHANGELOG.md at the repository root is where the project records what changed. The README itself does not document a rollback path or a deprecation schedule, so treat the changelog as the source of truth before moving a production site across a major version.

Upgrade cost is mostly proportional to how much of the formatter API you touch. If you use the stock HTML formatter and a built-in theme, a major bump is usually a version line in your Gemfile. If you wrote a custom formatter against #stream or #safe_span, those are the methods to re-check, because they are the documented extension points and therefore the ones most likely to move.

On licensing: the repository metadata reports the licence as NOASSERTION, which means the automated classifier could not map the LICENSE file to a known identifier. The LICENSE file is present at the repository root. Read it directly rather than assuming MIT or any other standard licence, and if you are redistributing Rouge or its generated CSS, have someone qualified confirm what the file actually permits. That is a factual gap in the metadata, not a legal opinion.

Editorial conclusion

Adopt Rouge if you are already in Ruby or Jekyll and want highlighting with no Python or native extension in the stack; the gem installs with one line and rougify covers terminal and CSS generation. Do not adopt it if you need Pygments' full language list, its exact token stream, or a theme ecosystem larger than the built-in set, because Rouge's compatibility promise is about HTML output and stylesheets, not about being a drop-in Pygments replacement at the lexer level. Before committing, verify that your target language has a lexer in the Languages documentation and that the theme you want exists under Rouge::Theme, since the README does not document a theme fallback path.

Frequently asked questions

What is Rouge?

Rouge is a pure Ruby syntax highlighter that supports over 200 languages and outputs HTML or ANSI 256-color text. Its HTML output is compatible with stylesheets designed for Pygments, and it is Jekyll's default syntax highlighter.

How do I use Rouge to highlight a file?

Install the gem, then run the rougify command on the file, for example rougify foo.rb. You can pick a theme with -t, as in rougify foo.rb -t monokai.sublime, or export that theme's CSS with rougify style monokai.sublime > syntax.css.

How do I install Rouge?

The README gives two options: add gem 'rouge' to your Gemfile, or run gem install rouge from the command line. Rouge then works as a Ruby library, as part of Jekyll, or through the rougify command.

Is Rouge the same as Pygments?

No. Rouge is a pure Ruby highlighter whose HTML output is compatible with Pygments stylesheets, which means the CSS classes line up. The README does not claim that Rouge's lexers produce the same tokens as Pygments for every language.

Does Rouge come with Jekyll?

Yes. The README states that Rouge is Jekyll's default syntax highlighter and that it is used out of the box to highlight text wrapped in the {% highlight %} template tags, where you can specify the language and whether to enable line numbers.

Can I write my own formatter for Rouge?

Yes, and the README encourages it for custom presentation. Subclass Rouge::Formatter, define a tag, and implement #stream(tokens, &block); the base class provides #token_lines and the HTML formatter provides #span and #safe_span as helpers.

Official sources

  1. Issues
  2. Project website
  3. README
  4. Releases
  5. rouge-ruby/rouge on GitHub
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/rouge-ruby-rouge.svg)](https://hysenlabs.com/projects/rouge-ruby-rouge)