September 29, 2019
I am happy to announce the release of elm-review
and its CLI.
elm-review
is a tool that analyzes your project’s Elm code, and reports patterns that do not comply with a set of “rules”.
Let’s say that in your Elm project, there is a Ui.Button
module, so that the project has a consistent UI for your buttons, and a better API for your use case to avoid pitfalls the team has too often fallen into. Also, in order to have a consistent color palette, there is a module named Ui.Color
which contains all the definitions for the colors in your application.
The problem is that, sometimes these conventions are forgotten or were not well communicated, and problems appear. The native Html.button
function gets used instead of the Ui.Button
module, and colors often get redefined where they are used and not imported from Ui.Color
. Sometimes, these get noticed during code review, but sometimes they don’t.
elm-review
provides you the ability to write rules that make this code review automatic. The result could look something like this:
The recommended way to get elm-review
is to install the CLI, available on npm
.
npm install elm-review
You can then use it in your terminal as elm-review
. I suggest starting with running elm-review --help
and elm-review init
, which will guide you into using and configuring elm-review
. I suggest reading at least the section on when to write or enable a rule before you start adding plenty of rules to your project.
You can also try it in an online version here, or you can checkout this repository that shows how elm-review
is configured and used. The screenshot above was taken from this example.
A lot of static code analysis tools out there (for any language) provide a set of “rules” that you can enable and/or configure, but only some provide the ability to write your own custom rules. Custom rules can be a great tool to forbid things in your project, that are not possible with language constructs, in order to create more guarantees.
The button and color examples I have talked about before are not something that makes sense to be forbidden by the compiler, since the problem is too dependent on the project and the way the team works. Also, it is not possible to forbid this using APIs, even by using techniques like opaque or phantom types, because your API can not restrict the use of a data type from a different module.
Review rules are written in Elm. This means that you don’t need to learn a different language to be able to write one, and this also means that rules can be published and shared on the Elm package registry. You can go to the package documentation to learn how to write rules, where you can find a lot of rule examples that might inspire you to write your own to solve problems you have.
Even though elm-review
can help you with enforcing a given code style, I recommend not using elm-review
for this purpose. For most of the styling issues, we have elm-format
. Also, though a review rule can be a powerful tool, it may not be the best solution to solving your problem, nor the first one to reach for. Other solutions, like API changes, should be considered first. I suggest reading when to write or enable a rule for more on that.
The errors reported by elm-review
are meant to be as helpful as possible. They try to explain what the reported problem is, why the pattern is forbidden and how to improve the code so as not to have the problem, like what we are used to with Elm’s compiler errors. I don’t have full control over the details of the review errors other people will write, but this is what the API and the documentation guide towards.
In the previous example about forbidding the creation of colors outside the Ui.Color
module, I would detail in the error message why we don’t allow colors to be defined elsewhere, and explain the steps on how to fix the problem.
elm-review
supports automatic fixes. This means that you can write a rule that suggests a solution to the reported problem. When running elm-review
, it will tell you when an automatic fix is available for the problem. If you run elm-review --fix
, you will be presented with automatic fixes one by one and you will be able to apply or ignore them.
Even though the functionality exists, I think automatic fixes should only be provided in restricted cases.
To help you write great rules, elm-review
provides a testing module that works with elm-test
that helps you test them in depth. If you’re interested, you can read the design goals for this module.
Unlike most static code analysis tools, elm-review
comes with no rules included. That is because I do not want to suggest that some rules are best practices, and I wish for users to decide what is best for them.
Coming with 0 rules doesn’t mean that you need to write them all yourself. Instead, you can find some in the Elm packages, and a good way to find them is by using elm-search
and searching for Review.Rule.Rule
. I have published a few ones already: jfmengels/review-unused to find dead code and remove it, and jfmengels/review-debug to find occurrences of Debug
code.
In the Elm community, we already have a similar tool: elm-analyse. The main difference between the two, in my opinion, is the ability to write your own rules. For the rest, there are plenty of differences but in the end they are quite similar.
elm-analyse
currently has some great features that elm-review
doesn’t (but maybe one day), like a watch mode, better performance (probably), better operating systems support (probably) and is integrated in some editors. elm-analyse
also has useful features that elm-review
doesn’t aim to have, such as indicating that a new version of a dependency is available or generating a module graph.
On the other hand, elm-review
has I think a more correct configuration method: the configuration is written in Elm, meaning misconfiguring elm-review
means it won’t compile. In elm-analyse
the default configuration would be used if the configuration has syntax errors, and the settings are ignored if you make typos or pass unknown fields. The rules are opt-in in elm-review
, meaning you specify those you wish to enforce, whereas in elm-analyse
they are opt-out, meaning you specify those you wish to ignore. elm-review
also has the ability to review other files than those in source-directories
or src/
, meaning you can review your test files or even your review configuration.
If you like elm-analyse
’s rules and don’t need any custom rules, I suggest using it. If you need other rules than that, custom rules or ones available on the Elm package registry, maybe try elm-review
. And nothing prevents you from using both!
I think that elm-review
lowers the barrier to entry to the realm of static code analysis, thanks to a great API, and by allowing anyone to use a rule without the maintainer of the tool’s consent and effort. I believe that this will, in turn, make people create new useful and awesome rules for everyone to use. Here is a list of rule ideas that I have. Maybe these will inspire you with great rule ideas.
First of all, I would like to make sure that elm-review
is working well and as expected, and that people are finding uses for it. I want to make sure that writing rules and testing them all have a great experience.
I also think that elm-review
’s configuration API will need to change to accommodate exceptions, different rules for different folders (src/ vs tests/ for instance), but this will depend on the pain points that users will give as feedback.
Some of the things I then want to work on include:
elm-review
working on very big projects, in a reasonable time.elm-xref
does. I am very concerned about the performance implications of this, and have mostly therefore left it for later, but doing this would allow for much more advanced and helpful rules: much better dead code elimination detection, detecting dead internal links in documentation, detecting unused dependencies…I hope you will try elm-review
and enjoy it. I spent a lot of time polishing these projects, but ultimately there are some edges where I need feedback from other users.
If you wish to talk about elm-review
or send me feedback, hit me up on the Elm Slack (@jfmengels), or open a GitHub issue in the appropriate repository.
Thank you for reading!
Written by Jeroen Engels, author of elm-review. If you like what you read or what I made, you can follow me on Twitter or sponsor me so that I can one day do more of this full-time ❤️.