Library / SDK
ccampbell/rainbow avatar
ccampbell/rainbow

Rainbow: A Small JavaScript Syntax Highlighter with a Node API and CSS Themes

GitHub describes it as Simple syntax highlighting library written in javascript. The repository metadata lists JavaScript as its primary language. The metadata lists the Apache-2.0 license. This article stays within the project description and details documented in the GitHub repository README.

3,295 stars448 forksJavaScriptApache-2.0

At a glance

What is it?
Rainbow is a lightweight JavaScript syntax highlighting library that works in the browser and Node.js. It offers a small core, CSS-based theming, and a straightforward extension API, but its development has stalled since 2020.
Who is it for?
Adopt Rainbow if you need a minimal, dependency-free highlighter for simple websites or Node scripts, and you are comfortable writing your own language rules for anything beyond the 19 bundled languages. Do not choose it if you need active maintenance, modern JavaScript features like lookbehind in regex, or a large language catalog.
Can I use it commercially?
Yes. Apache-2.0 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?
Probably not. The repository last received commits 37 months ago, on September 24, 2023.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • ccampbell/rainbow3,295 ★ · -4
Star history
Repository2026-08-132026-10-22
ccampbell/rainbow3.3k3.3k

-4 Stars in the last 70 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

What Rainbow Solves and Who It Is For

Rainbow addresses the problem of syntax highlighting on web pages without pulling in a heavy dependency. The README states it is lightweight, around 2.5kb, easy to use, and extendable. That size matters for sites where every kilobyte counts, such as landing pages, documentation sites, or embedded code snippets. The library is aimed at developers who want a simple drop-in script that highlights code blocks automatically on page load, without configuration. It also targets Node.js users who need to highlight code outside the browser, a feature introduced in version 2.0. If you are building a static site generator or a command-line tool that outputs highlighted code, Rainbow's Node API gives you that capability. It is not designed for large-scale applications with complex theming needs or for real-time code editing, where more robust solutions exist.

How Rainbow Works: Automatic Highlighting and Language Detection

Rainbow works by scanning the DOM for code blocks and applying syntax highlighting based on a language attribute. The README explains three ways to specify the language: a data-language attribute on the code element, an HTML5 class like language-javascript, or a Google prettify style class like lang-javascript on the pre element. When the page loads, Rainbow.color is called automatically on DOMContentLoaded, so you do not need to invoke anything manually. The library then tokenizes the code using regular expressions defined per language. Each language file, such as python.js or javascript.js, contains patterns that match keywords, strings, comments, and other constructs. The core Rainbow object orchestrates the matching, and it uses a specific order to decide which pattern wins. The documentation describes three match types: match by name, match by group, and match by array of sub-patterns. You can also match using another language, which allows one language to reuse rules from another. This mechanism is what makes Rainbow extensible, but it also imposes constraints on the regular expressions you can write, as discussed later.

Getting Started: Installation and Basic Usage

To use Rainbow in the browser, you include a CSS theme file in the head, then load rainbow.js and the language files before the closing body tag. The README gives a concrete example: link a theme.css, then add script tags for rainbow.js, language/generic.js, and language/python.js. The default dist/rainbow.min.js comes with some popular languages bundled, so you may not need separate language files for common cases. For Node.js, you install the package with npm install --save rainbow-code, then require it and call the colorSync method. The example shows: var rainbow = require('rainbow-code'); var highlighted = rainbow.colorSync('// So meta\nvar helloWorld = true;', 'javascript');. That method is synchronous, which is useful for scripts that need the result immediately. The API also includes Rainbow.color for asynchronous highlighting, Rainbow.extend for adding or overriding language rules, Rainbow.addAlias for language aliases, Rainbow.onHighlight for callbacks, and Rainbow.remove for cleanup. The build process uses gulp, with commands like gulp build, gulp lint, gulp pack, gulp sass, and gulp test, so if you want to create a custom package, you need a Node environment with gulp installed.

Theming and the 2-Second Fade-In Trick

Rainbow themes are written in SASS, located in the themes/sass directory. The README warns not to edit the CSS files directly because they are generated. Shared logic lives in _base.sass and _init.sass. A notable design choice is the rendering technique introduced in version 2.0: all code blocks default to opacity: 0, and an animation triggers on page load after a 2-second delay. If JavaScript is enabled, the animation is stopped and the delay is reset to 0s, so highlighted code appears instantly. If JavaScript is disabled, the code fades in after 2 seconds, which is a fallback for non-JS users. There is also a preload animation for code blocks that take longer than 300ms to highlight. This approach prevents a flash of unstyled text, but it means that without JavaScript, users wait 2 seconds before seeing code. That is a trade-off: it ensures no flash, but it introduces a deliberate delay for the no-JS case. The theme system also includes a SASS mixin called language, which lets you define styles for specific languages, as shown with @include language("html") { .support.operator { color: #fff } }. That gives fine-grained control over how each language is rendered.

Extending Languages: Power and Constraints

Rainbow.extend is the primary way to add or modify language rules. The README details several pattern types. You can match by name, where a pattern has a name like keyword and a regex. You can match by group, where the regex has capturing groups and each group maps to a class. You can match by array of sub-patterns, which lets you combine multiple regex patterns. You can also match using another language, which is useful for embedded code like HTML with JavaScript. The documentation also explains how Rainbow chooses a match when multiple patterns could apply, which is important for predictable highlighting. However, there are known limitations. The README explicitly mentions that regular expression lookbehind assertions are not supported, and that regular expression subgroup matches have limitations. This means you cannot write patterns that rely on lookbehind, which is a common technique in modern regex. That is a real constraint if you want to highlight context-sensitive constructs. The library is extensible, but you must work within these regex limitations.

Limitations and When Rainbow Is the Wrong Tool

Rainbow has several limitations that make it unsuitable for certain projects. First, the lack of lookbehind support in regular expressions restricts the complexity of language definitions. If you need to highlight code with patterns that require looking behind a token, you cannot express that directly. Second, the project has not been updated since September 2020, with the last release being 2.1.7. That means no fixes for browser compatibility issues that may have emerged since then. The supported browsers list includes Chrome 20+, Firefox 13+, IE 10+, and Safari 6+, which are ancient by current standards, but the library may still work in modern browsers. However, there is no guarantee. Third, the language catalog is limited to 19 languages: C, C#, Coffeescript, CSS, D, Go, Haskell, HTML, Java, JavaScript, JSON, Lua, PHP, Python, R, Ruby, Scheme, Shell, Smalltalk. If you need a language not on that list, you must write your own rules, which is non-trivial given the regex constraints. Fourth, the 2-second fade-in for no-JS users could be a problem for accessibility or for users on slow connections. Finally, the build process relies on gulp and SASS, which adds a toolchain requirement if you want to customize themes or build custom packages. For a project that is supposed to be simple, that is a barrier.

Alternatives and How They Differ

The most common alternative is Prism, a syntax highlighter that also runs in the browser and supports Node.js. Prism takes a different approach to extensibility: it uses a plugin architecture and a larger set of built-in languages, and it does not rely on a data-language attribute alone; it uses class names like language-javascript as well. Prism also supports lookbehind in its regex patterns, which Rainbow explicitly does not. That is a significant difference because it allows Prism to handle more complex syntax rules. Another alternative is highlight.js, which uses a single JavaScript file with many languages bundled and auto-detects the language when no language is specified. Rainbow requires you to specify the language unless you use a generic language file, but the README mentions a generic.js, which likely provides basic highlighting without specific language rules. highlight.js also has a larger community and more frequent updates. The key difference in approach is that Rainbow keeps the core minimal and requires you to load language files, while Prism and highlight.js offer more out of the box. If you need a single-file solution with many languages, highlight.js is simpler. If you need fine-grained control over patterns and are willing to write rules, Rainbow's extend mechanism is flexible, but you must accept the regex limitations.

Maintenance, License, and Upgrade Cost

The repository shows no activity since September 2020, and the last release was 2.1.7. That means the project is effectively unmaintained. There is no indication of ongoing development or community support. The license is Apache-2.0, which is permissive and allows commercial use, modification, and distribution, but you should read the license terms yourself for your specific use case. The upgrade cost is low if you are already using an older version, because the API has been stable since 2.0, but moving from 1.2.0 to 2.x introduces the Node API and the new theme rendering trick, which may change the visual behavior. The build system uses gulp, so if you need to modify themes or languages, you must set up a Node development environment and run gulp commands. That is a maintenance overhead that you should factor in. Since the project is not maintained, you would be responsible for any bug fixes or compatibility updates yourself. For a small static site, that may be acceptable, but for a long-lived project, it is a risk.

Editorial conclusion

Adopt Rainbow if you need a minimal, dependency-free highlighter for simple websites or Node scripts, and you are comfortable writing your own language rules for anything beyond the 19 bundled languages. Do not choose it if you need active maintenance, modern JavaScript features like lookbehind in regex, or a large language catalog. Before adopting, verify that the 2.1.7 release works in your target browsers (Chrome 20+, Firefox 13+, IE 10+, Safari 6+) and that the 2-second fade-in animation for no-JS users is acceptable. Also confirm that the Apache-2.0 license fits your project, and test the custom theme build process with gulp, since the project has not seen a commit since September 2020.

Frequently asked questions

How do I install Rainbow for Node?

Run `npm install --save rainbow-code`. The package name on npm is rainbow-code, and its main entry is ./src/rainbow-node.js rather than a file in dist.

Which languages does Rainbow support?

Nineteen: C, C#, Coffeescript, CSS, D, Go, Haskell, HTML, Java, JavaScript, JSON, Lua, PHP, Python, R, Ruby, Scheme, Shell and Smalltalk. In the browser you include rainbow.js plus one file per language.

What does Rainbow do when JavaScript is disabled?

Since 2.0 all code blocks default to opacity 0 with an animation that fires after a 2 second delay. Without JavaScript the animation is not stopped, so code appears once that delay expires instead of instantly after highlighting.

Which browsers does Rainbow support?

Version 2.0 targets Chrome 20 and later, Firefox 13 and later, Internet Explorer 10 and later, and Safari 6 and later. Older browsers are pointed at the separate 1.2.0 release.

What is the newest released version of Rainbow?

2.1.7, tagged on 2020-09-12 alongside 2.1.5 and 2.1.6, all within about two minutes of each other. The default branch master has been pushed to as recently as 2023-09-24, which is later than any tag.

Official sources

  1. Official documentation
  2. Official README
  3. Project repository
  4. Release notes
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/ccampbell-rainbow.svg)](https://hysenlabs.com/projects/ccampbell-rainbow)

Star history chart for your README

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