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

Rouge tells you to write your own formatter and documents eleven, and its own project link points at a different domain than its homepage

A pure Ruby code highlighter that is compatible with Pygments

3,457 stars821 forksRubyNOASSERTION

At a glance

What is it?
Rouge is a pure-Ruby syntax highlighter for over two hundred languages with Pygments-compatible HTML output, shipped as a gem with a command line tool and used as Jekyll's default highlighter. Its configuration section documents eleven formatters, two of which are line tables whose option lists overlap almost exactly, one of which is a compatibility shim over three others, and its reference link definition names a project domain that differs from the homepage field.
Who is it for?
Use Rouge if you are in the Ruby ecosystem and want highlighting that is both a library and a command line tool, because the two are the same gem and the command line is a genuine part of the interface rather than a developer convenience. It is also the right choice if you need HTML that drops into Pygments stylesheets without writing a wrapper.
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 16 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 November 14, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • rouge-ruby/rouge3,457 ★ · +5
Star history
Repository2026-09-242026-11-14
rouge-ruby/rouge3.5k3.5k

5 Stars in the last 51 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

The project's own reference link names a different domain than its homepage

One project address is recorded for the site, and the README's reference link definition records a different one.

The metadata names a Canadian domain. The README's link definition for the project name points at a different domain with a different country code, over plain http rather than https.

So a reader who clicks the project's own name in the README, which is how the opening sentence refers to the library, lands somewhere other than the address the repository advertises.

The same pattern runs through the rest of the reference definitions. The languages page is on a documentation subdomain, which is also what the third badge links to, so that one is consistent. The reference for the highlighter whose stylesheets Rouge is compatible with is also plain http.

Three of the six link targets in that block, plus one badge, use http. For a library whose entire output is HTML that gets embedded in other people's pages, a README that hands out insecure links for its own documentation is a small but real inconsistency, and the two domains are the part that matters: one of them is a legacy address that a current reader has no way to know is superseded.

Six of the eleven formatters target one specific output each

The configuration section documents eleven formatters, and most of them exist for a narrow reason that the README states in a sentence.

There is one that emits plain HTML with standard token class names and no wrapping elements. There is one that emits no class names at all and inlines the styles into the style attribute, which the file recommends for email and other places with minimal CSS support. There is one that puts each line in its own div, one that wraps a configurable set of line numbers in a span with a chosen class, one that produces a table with one row per line, one that produces a table with a single row, and one that wraps another formatter in the div structure that Pygments stylesheets expect.

There is one that is a compatibility class for the previous major version, one that emits 256-colour terminal codes, one that emits true-colour terminal codes instead of approximating, and one that wraps tokens in a macro for a TeX system.

Read as a list, that is a small library of output shapes rather than eleven ways of doing the same job. The two that matter most for most users are the first two, and the file's own framing agrees: it says that as of version 2.0 you are encouraged to write your own formatter if you need something custom, and then gives you the eleven.

The two table formatters share three option names and drop a fourth

Two of the eleven produce an HTML table of numbered lines, and their option lists are nearly identical in a way that makes them hard to tell apart.

Both take a starting line number, and both name a CSS class for the gutter cell and one for the code cell, with the same values in both. Both produce a table class, with different values.

Then they diverge. The per-line version takes a class for each row and a template for the identifier attribute of each row. The single-row version takes neither: instead of a row class and a row identifier template, it takes a template for the line number itself, because there is only one row.

So the two option lists differ by exactly one removed name and one replaced name, and the replacement has a different purpose: a row identifier in one case, a rendered number in the other.

The file does explain the difference in output, and it is a real one: the single-row table is friendlier for scripting over the document, but long code lines will break its column alignment. What it does not do is warn that the two formatters' option names are close enough to be guessed wrong, which is exactly the failure mode when you copy an options hash from one to the other.

One formatter is a shim over three others

One entry in the list is not a formatter at all in the way the others are. It is described as a backwards-compatibility class for users of the previous major version, with the options that were supported then.

Its four options each delegate to another formatter in the same list. One switches to the inline formatter with a given theme. One switches to a table formatter, and its default is off. One switches to the Pygments-compatible wrapper, and its default is on. The fourth is a class name for that wrapper.

So one of the eleven is a façade over three of the other ten, and it exists so that code written against the old version keeps working.

That is a reasonable thing to ship and it is also the reason the list is eleven long rather than ten. A reader counting formatters to choose one will include it, and a reader maintaining an application with a pinned old version will be glad it is there.

What is missing is a note that it is a shim. Nothing in the entry says these options will be removed, or points at the version where the shim goes away, so a user who finds it has no way to learn that the modern equivalent is three separate formatters.

The tutorial for writing your own formatter stops in the middle of its loop

The README's most useful section for anyone extending the library ends mid-statement.

The prose before the example is good. Subclass the base formatter class, define a tag, implement a method that receives token and value pairs and yields out chunks to be concatenated. Two helper methods are named, one on the base class that separates tokens into lines and one on the HTML formatter that escapes and renders span tags, plus an override point for changing how an individual span is rendered.

Then the code example opens. It subclasses the HTML formatter, the main entry method carries a comment explaining that it receives an enumerable of pairs and should yield fragments, the method yields an opening div with a class of its own, and then the loop begins.

And the example stops there, in the middle of the destructuring in the loop header.

So the one thing the README tells you to do yourself is demonstrated to the exact point where it starts being interesting, and the fragment you are given ends with an unfinished line.

Everything after it, in the file, is truncated too, so the closing advice is not available either. The prose is enough to get started; the code is not enough to copy.

The command line accepts a Sublime Text theme file as its theme argument

The command line tool is three lines of example, and all three are worth reading.

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

The first line highlights a file with the default settings. The second passes a theme, and the theme is given as a path to a file with the extension of a different editor's colour scheme.

So the library reads another editor's theme format rather than only its own. That is a deliberate interoperation decision: a user moving from that editor to a Ruby toolchain gets their colours for free, and the file uses a well-known theme name to demonstrate it.

The third line is the interesting one. A style subcommand takes the same theme and writes a stylesheet to standard output. That means the theme file is the interchange format in both directions: you can highlight with a theme someone else wrote, and you can generate a stylesheet from it for a web page.

The gem name, the library name and the command all differ by a suffix, which is the only friction here and is exactly what a package manager handles.

A lint to-do file and a committed temporary directory

Two entries at the repository root describe how the project is worked on rather than what it does.

There is a linter configuration and a second file beside it whose name marks it as a to-do: a list of violations the project has accepted and intends to fix later. For a library whose README tells you to write your own formatter, the existence of an outstanding lint list is worth knowing about, because it tells you the codebase has accumulated warnings that are being tracked rather than fixed.

There is also a temporary directory, committed. Whatever it holds, it is not meant to be there.

Everything else in the root is conventional: a gem specification, a gemfile, a rakefile, a tasks directory, a spec directory, a library directory, a directory of generated documentation with its own options file, a watch configuration for a file-watcher, a Rack configuration file at the root, and an agent instruction file.

The Rack file is the one that hints at scope the README does not mention. A syntax highlighter as a gem does not need a Rack application entry point; something in this repository serves over HTTP.

The releases land on a weekend and a New Year's Eve

The three newest release dates are worth reading for their pattern.

One was published on the last day of December. The next came in late May, and the newest in early August. All three are minor version bumps.

That tells you the cadence is roughly quarterly and that the maintainer publishes when the work is done rather than on a schedule. The December release landing on New Year's Eve is consistent with that.

What the dates do not tell you is the compatibility story. A library whose minor version moved twice in the visible history, and whose formatter guidance dates from a much older major version, is signalling that the major number is the thing to watch.

For a user the practical consequence is small: pin the version, and read the changelog in the repository rather than trusting the release note titles, which in the visible history are just the version numbers repeated.

Editorial conclusion

Use Rouge if you are in the Ruby ecosystem and want highlighting that is both a library and a command line tool, because the two are the same gem and the command line is a genuine part of the interface rather than a developer convenience. It is also the right choice if you need HTML that drops into Pygments stylesheets without writing a wrapper. Three things to check before you commit. Which formatter you actually need, because there are eleven documented and the README recommends writing your own, so the choice is yours to make rather than the library's. Which domain you trust for the project site, because the README's own reference link and the repository's homepage field name two different addresses. And what you will do about maintenance signals, since the repository's licence field reports nothing recognised while a licence file sits at the root, so read the file rather than the metadata if that matters to you.

Frequently asked questions

What is Rouge?

It is a pure Ruby syntax highlighter that can highlight over two hundred languages and output either HTML or 256-colour terminal text, with HTML output compatible with stylesheets designed for Pygments. It is installed as a gem, either by adding it to a gemfile or with the gem installer, and the README lists three uses: as a library, as part of Jekyll, and as a command line tool called rougify.

how to use rouge

As a library you require it, construct a formatter and a lexer, format the lexed tokens, and optionally render a theme's stylesheet for a selector. As a command line tool, rougify highlights a file, accepts a theme path after a flag, and can write a stylesheet to standard output with a style subcommand. The themes it accepts include files written for a different code editor.

Is Rouge the default syntax highlighter in Jekyll?

Yes. The README states that Rouge is Jekyll's default highlighter and that text wrapped in the highlight template tag is highlighted out of the box. It also notes that the tag offers minimal options, namely which language to use and whether to enable line numbers, with more detail in the Jekyll documentation.

Why does Rouge ship eleven formatters when it tells you to write your own?

The README says that as of version 2.0 you are encouraged to write your own formatter if you need something custom, and then documents eleven built-ins. They are mostly narrow outputs: plain HTML with token classes, inline styles for email, per-line divs, highlighted line spans, two table layouts, a Pygments-compatible wrapper, a compatibility class for the previous major version, two terminal colour depths, and a TeX tag emitter.

What is the difference between Rouge's two HTML table formatters?

One puts each line in its own table row and the other puts everything in a single row, which the README says is friendlier for scripting over the document but will break column alignment on long lines. Their option lists share a starting line number, a gutter class and a code class, but the per-line one takes a row class and an identifier template, while the single-row one takes a template for the line number text instead.

Does the rouge syntax highlighter send anything over the network?

Nothing in the repository suggests that it does. The tree is a gem, with a library directory, specs, rake tasks and a Rack configuration file at the root, and the documented installation is a gem add. The three documented uses are a library, Jekyll, and a command line tool. The README does not describe any network or telemetry behaviour.

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)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/rouge-ruby-rouge.svg)](https://hysenlabs.com/projects/rouge-ruby-rouge)

Was this useful?