reek parses with whichever Ruby you run it on, ships two detectors switched off, and its own container pins Ruby 2.6
Code smell detector for Ruby
At a glance
- What is it?
- troessner/reek is a MIT-licensed code smell detector for Ruby that examines classes, modules and methods and reports warnings with line numbers. It officially supports CRuby 3.0 through 3.3 and JRuby 9.4, it uses the parser belonging to the Ruby it is running under, its sample tree holds fixture directories plus a Checkstyle document, and its Code Climate container image is built on an Alpine Ruby two major versions below its own supported range.
- Who is it for?
- reek fits a Ruby codebase that has accumulated design-level smells nobody wants to argue about in review, because its detectors are deliberately narrow and two of the most contentious ones are switched off until you ask for them, which means the first run on an existing project will not bury you in output. It does not fit a team looking for a general-purpose linting umbrella, since it inspects structure and naming rather than formatting and style.
- 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 28 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.
Star history
- troessner/reek4,138 ★ · +8
| Repository | 2026-09-23 | 2026-11-14 |
|---|---|---|
| troessner/reek | 4.1k | 4.1k |
8 Stars in the last 52 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
The parser comes from whichever Ruby you are running under
This is the single most consequential sentence in the documentation and it is easy to skim. Reek officially supports CRuby 3.0 through 3.3 and JRuby 9.4, other implementations are unsupported but expected to work, and then comes the note: on each Ruby version, the tool uses the parser for that version of Ruby, so you should always run it using one of your project's target Ruby versions.
Installing it is one command from the RubyGems registry:
gem install reekand the usage line is a list of options followed by directories or files, all optional:
reek [options] [dir_or_source_file]*Ruby ships several parsers, they track each other closely, and a smell detector is only as good as its view of the syntax. That makes the interpreter a functional dependency rather than an environmental detail, and it has a practical consequence for continuous integration: running the detector on a newer Ruby than the project targets is not a neutral act, and running it on an older one can produce different warnings for the same file.
Two detectors ship switched off because the project calls them controversial
Nine named smells are listed as currently implemented, from control coupling and data clumps through feature envy, large classes, long parameter lists, simulated polymorphism, too many statements and uncommunicative names to unused parameters, and the documentation defers to a separate page for the authoritative list. The interesting part is the section headed as special configuration for controversial detectors. One detector, unused private method, is disabled by default and the reason is stated plainly: it is controversial, with a link to the discussion, so you have to activate it explicitly in your configuration. A second, utility function, is described as controversial too and as potentially unforgiving, and instead of being switched off it can be limited to public methods with a single option. Both are the kind of decision a maintainer makes when a check produces confident, wrong output.
The samples directory is a fixture tree, and one sample is a Checkstyle file
The samples directory is not example code you would want to copy. It is a set of fixture trees used by the test suite, and the names are the documentation: a clean source directory, a smelly source directory, a configuration directory, a no-configuration-file case, a source with exclude paths, a source with hidden directories, a source with non-Ruby files, and a small Ruby file of paths. Two files in there are less obvious. One is a Checkstyle document, which is a Java tool's report format, and its presence suggests the output layer is tested against a format Reek does not natively produce. The other is the paths file, which suggests path handling is tested separately from source inspection. Between them they explain why the repository has both a unit test directory and a directory named for behavioural tests rather than only one.
The container pins a Ruby two majors below the supported range
The container file is not the container for running reek on your project. Its first line points at the Code Climate engine specification, its build comment shows an image name in that vendor's namespace, and its entry point is a script named for the Code Climate engine rather than the tool. It also starts from an Alpine Ruby image two major versions older than the oldest version the project officially supports, installs the build toolchain, installs dependencies with two groups excluded, and installs the vendor's Ruby engine package. It then uses a maintainer instruction that current tooling treats as deprecated, and it sets its environment variables in the old space-separated form. None of this breaks anything, but it means the container you would naturally reach for first is built for a code quality service integration and is pinned to an interpreter the project no longer claims to support.
The project runs its own detector on itself and keeps a lint todo file
The root directory contains a configuration file for the detector itself, which means the maintainers run the tool on their own code rather than exempting themselves. Next to it is a RuboCop configuration, a separate file whose name ends in a todo, and a coverage configuration, and a documentation generator options file. The todo file is the one worth understanding: it is a list of style violations that are knowingly outstanding, which is the standard way a project adopts a linter without rewriting its history in one commit, and it tells a reader that the Ruby code here has known style debt that is being worked down rather than fixed. The gemspec, a Rakefile, a task directory and a bundle definition sit beside them, which is the conventional Ruby project skeleton from before most of these tools were written in another language.
No argument means the current directory, and piped code gets a name
Source handling has three behaviours and the third is the one that catches people out. Passing a directory is the common case. Passing nothing is documented as exactly equivalent to passing a dot, so with no arguments the tool inspects the current working directory rather than doing nothing. And code can be piped in, with the example being a class definition echoed into the tool, which then reports three warnings against a pseudo-file named for standard input, using the same format as a real file. That last detail is useful rather than cosmetic: it means you can check a snippet without writing a file, and it means scripts that filter output by filename need to handle a name that no file has.
The tool declines to tell you how to fix a warning
The section on fixing warnings opens by refusing the request, and it is a considered refusal rather than an omission. Reek focuses on high-level smells, so it says it cannot tell you how to fix warnings in a generic way because that depends on your domain language and business logic, and that this will always be true. What it offers instead is a worked example: a Rails model whose method sums a net and a tax value over a collection of items, which produces a feature envy warning because the method refers to the item more than to itself. The fix shown is to move the per-item calculation onto the item class. So the guidance is a pattern rather than a rule, and the warning itself is the diagnosis. That combination is the difference between a tool that nags and a tool that teaches.
Configuration is found by walking up the directory tree
The configuration file is a YAML file with a dot-prefixed name, and the documentation insists that configuring through it is by far the most powerful way. The filename can be overridden from the command line. There are three ways to get a configuration to the tool, and the second is the interesting one: a configuration file in the current working directory or in a parent directory, which means walking up the tree until one is found. The documentation has its own subsection warning about multiple configuration files, which is the predictable consequence of a discovery rule that can cross directory boundaries. If you are reviewing a warning that you cannot explain, the parent directory is the first place to look, and it is also the reason a repository can pick up rules from a checkout higher up than the one you meant.
Editorial conclusion
reek fits a Ruby codebase that has accumulated design-level smells nobody wants to argue about in review, because its detectors are deliberately narrow and two of the most contentious ones are switched off until you ask for them, which means the first run on an existing project will not bury you in output. It does not fit a team looking for a general-purpose linting umbrella, since it inspects structure and naming rather than formatting and style. Two things to check before you adopt it. Which Ruby you run it under, because the documentation says explicitly that the tool uses the parser for the version it is running on and that you should therefore run it with one of your project's target versions, so a container with the wrong interpreter can parse your code differently. And which configuration file wins, since a configuration is found by walking up from the working directory and a parent directory can therefore supply rules you did not write.
Frequently asked questions
What is reek?
Reek is a MIT-licensed code smell detector for Ruby. It examines Ruby classes, modules and methods and reports the smells it finds, with a line number and a smell name for each, for example an uncommunicative method name or feature envy. It is installed with the RubyGems install command and run against a directory, a file, or code piped into it.
Which Ruby versions does reek support?
Officially CRuby 3.0 through 3.3 and JRuby 9.4. Other implementations such as Rubinius are not officially supported but are expected to work. The documentation also notes that on each Ruby version the tool uses the parser for that version, and recommends running it with one of your project's target Ruby versions.
How do I turn off a reek warning?
Two detectors are off or limited by default because the project considers them controversial. Unused private method is disabled until you enable it explicitly in the configuration file. Utility function is enabled but can be limited to public methods only. Everything else is switched on, and the full list of what is checked lives in the code smells documentation rather than in the readme.
Does reek have a configuration file?
Yes, a YAML file with a dot-prefixed name, and the filename can be overridden with a command-line switch. It is found in three ways: passed on the command line, present in the current working directory, or present in a parent directory, which means the tool walks up the tree. The documentation has a dedicated subsection about the problem of multiple configuration files.
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/troessner-reek)Star history chart for your README
[](https://hysenlabs.com/projects/troessner-reek)Was this useful?