{"id":13561749,"url":"https://github.com/jfmengels/elm-review","last_synced_at":"2025-05-15T23:07:49.875Z","repository":{"id":41251397,"uuid":"211512078","full_name":"jfmengels/elm-review","owner":"jfmengels","description":"Analyzes Elm projects, to help find mistakes before your users find them.","archived":false,"fork":false,"pushed_at":"2025-02-13T13:02:04.000Z","size":6926,"stargazers_count":268,"open_issues_count":18,"forks_count":13,"subscribers_count":10,"default_branch":"main","last_synced_at":"2025-04-08T10:33:41.847Z","etag":null,"topics":["code-quality","elm","elm-lang","elm-review","linter","quality","static-code-analysis"],"latest_commit_sha":null,"homepage":"https://package.elm-lang.org/packages/jfmengels/elm-review/latest/","language":"Elm","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jfmengels.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE-OF-CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":"SUPPORT.md","governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"jfmengels"}},"created_at":"2019-09-28T14:23:10.000Z","updated_at":"2025-04-05T06:19:54.000Z","dependencies_parsed_at":"2024-04-07T22:28:02.226Z","dependency_job_id":"3115f683-f1f6-409a-a040-38eebd41b53d","html_url":"https://github.com/jfmengels/elm-review","commit_stats":{"total_commits":2998,"total_committers":12,"mean_commits":"249.83333333333334","dds":0.009339559706470935,"last_synced_commit":"e762e863ef59110d35cfd391bb8ad2ee46f0ed7d"},"previous_names":[],"tags_count":50,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jfmengels%2Felm-review","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jfmengels%2Felm-review/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jfmengels%2Felm-review/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jfmengels%2Felm-review/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jfmengels","download_url":"https://codeload.github.com/jfmengels/elm-review/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254436949,"owners_count":22070947,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["code-quality","elm","elm-lang","elm-review","linter","quality","static-code-analysis"],"created_at":"2024-08-01T13:01:00.701Z","updated_at":"2025-05-15T23:07:43.858Z","avatar_url":"https://github.com/jfmengels.png","language":"Elm","funding_links":["https://github.com/sponsors/jfmengels"],"categories":["Linters","Static analysis","Elm"],"sub_categories":["Elm","Outdated Boilerplates"],"readme":"# elm-review\n\n`elm-review` analyzes [Elm](https://elm-lang.org/) projects, to help find mistakes before your users find them.\n\n[![elm-review reporter output](https://github.com/jfmengels/elm-review/blob/2.2.0/documentation/images/elm-review-report.png?raw=true)](https://github.com/jfmengels/elm-review/blob/2.0.1/documentation/images/elm-review-report-hq.png?raw=true)\n\n## What does `elm-review` do?\n\n`elm-review` analyzes your source code, trying to recognize code that is known to cause problems.\nAll the rules describing problematic code are written in Elm, and `elm-review` does not come with built-in rules;\ninstead users are encouraged to write rules themselves and publish them as Elm packages, for everyone to benefit.\n[Search the package registry](https://klaftertief.github.io/elm-search/?q=Review.Rule.Rule) to find what's out there!\n\nEncouraging users to write rules also makes it easy to add custom rules that only apply to your project.\nSuch as rules that:\n\n  - enforce that e.g. image paths only live in an `Images` module, which other modules can reference.\n  - make everyone use a common `Button` component, instead of creating their own.\n  - help users of a library you made, to avoid making mistakes that your API could not prevent them from doing.\n\nBeware how and why you introduce rules in your project though.\nOften a good API, that guides users to correct solutions, is the best way to go, so instead of writing a rule, maybe there is an API that can be improved?\nBut if a rule seems like the best solution, remember to discuss it with your team.\nIt's easy to mix up patterns that are objectively bad, with patterns that you personally find problematic, and forbidding patterns that other people find useful can be very disruptive.\n\n\n## Try it out\n\nThe easiest way to run `elm-review`, if you have `Node.js` and `npm` installed, is to use the [`elm-review` CLI tool](https://github.com/jfmengels/node-elm-review).\n\n```bash\n# Save it to your package.json, if you use npm in your project.\n# This is the recommended way.\nnpm install elm-review --save-dev\n\n# Install globally. This is not recommended.\nnpm install -g elm-review\n```\n\nYou can also **try it out without installing it or configuring it** if you have Node.js installed.\nAll you need is to find a configuration on GitHub, and note that `elm-review` packages are encouraged to provide an example one. Once you found the configuration, run `elm-review` by specifying the name of the GitHub repository and the path to the configuration:\n\n```bash\nnpx elm-review --template jfmengels/elm-review-unused/example\n```\n\nDo you want to find and remove all the dead code in your project? Then run the following command (this might take a while if your project has a lot of dead code though!), and think about whether you want this goodness in your project!\n\n```bash\nnpx elm-review --template jfmengels/elm-review-unused/example --fix-all\n```\n\nMore information on that in [the CLI documentation](https://github.com/jfmengels/node-elm-review#try-it-out).\n\n\n## Configuration\n\n`elm-review` is configured through a `review/` folder in your project. It is a self-contained Elm project where you can\nspecify your dependencies, and write, import, and configure review rules.\n\nRules are configured in the `review/src/ReviewConfig.elm` file:\n\n```elm\nmodule ReviewConfig exposing (config)\n\nimport Review.Rule exposing (Rule)\nimport Third.Party.Rule\nimport My.Own.Custom.rule\nimport Another.Rule\n\n\nconfig : List Rule\nconfig =\n    [ Third.Party.Rule.rule\n    , My.Own.Custom.rule\n    , Another.Rule.rule { ruleOptions = [] }\n    ]\n```\n\n\n## Get started\n\nYou can get started with a fresh configuration by running the `elm-review init` command with the command line tool installed,\nwhich will add a `review` folder to your project.\n\nYou can also use an existing configuration using `elm-review init --template \u003csome configuration\u003e`.\nI created [some configurations](https://github.com/jfmengels/elm-review-config) that I believe can be good **starting** points.\n\n```bash\n# Start with an empty configuration\nelm-review init\n\n# Starter configuration for an Elm application\nelm-review init --template jfmengels/elm-review-config/application\n\n# Starter configuration for an Elm package\nelm-review init --template jfmengels/elm-review-config/package\n```\n\nOnce you have set up an initial configuration, you can add new rules. As `elm-review` does not\n[come with built-in rules](https://github.com/jfmengels/elm-review/blob/master/documentation/design/no-built-in-rules.md),\nyou can look for packages with rules on the [Elm package registry](https://package.elm-lang.org/) by searching for packages named `elm-review-`.\n\nOnce you've found a package that you like, you can install it with the `elm install` command, just like any other Elm project dependency.\n\n```bash\ncd review/ # Go inside your review configuration directory\nelm install authorName/packageName\n# then update your `review/src/ReviewConfig.elm` to add the rule\n# as explained in the package's documentation\n```\n\nBefore you start adding rules or an unfamiliar existing configuration, I suggest reading the rest of this document, especially the section on [when to enable a rule](#when-to-write-or-enable-a-rule).\n\n\n## Write your own rule\n\nYou can write your own rule using this package's API and [`elm-syntax`](https://package.elm-lang.org/packages/stil4m/elm-syntax/7.2.1/).\nCheck out the [`Review.Rule`](https://package.elm-lang.org/packages/jfmengels/elm-review/2.15.1/Review-Rule/) documentation for how to get started.\n\n**NOTE**: If you want to **create a package** containing `elm-review` rules, I highly recommend using the\n[CLI's](https://github.com/jfmengels/node-elm-review/) `elm-review new-package` subcommand. This will create a new package that will help you use the best practices and give you helpful tools like easy auto-publishing. More information is available in the maintenance file generated along with it.\n\nIf you want to **add/create a rule** for the package or for your local configuration, then I recommend using `elm-review new-rule`, which will create a source and test file which you can use as a starting point. For packages, it will add the rule everywhere it should be present (`exposed-modules`, README, ...).\n\n\nHere's an example of a rule that prevents a typo in a string that was made too often at your company.\n\n```elm\nmodule NoStringWithMisspelledCompanyName exposing (rule)\n\nimport Elm.Syntax.Expression as Expression exposing (Expression)\nimport Elm.Syntax.Node as Node exposing (Node)\nimport Review.Rule as Rule exposing (Error, Rule)\n\n-- Create a new rule\nrule : Rule\nrule =\n    -- Define the rule with the same name as the module it is defined in\n    Rule.newModuleRuleSchema \"NoStringWithMisspelledCompanyName\" ()\n        -- Make it look at expressions\n        |\u003e Rule.withSimpleExpressionVisitor expressionVisitor\n        |\u003e Rule.fromModuleRuleSchema\n\n-- This function will visit all the expressions (like `1`, `\"string\"`, `foo bar`, `a + b`, ...)\n-- and report problems that it finds\nexpressionVisitor : Node Expression -\u003e List (Error {})\nexpressionVisitor node =\n    case Node.value node of\n        -- It will look at string literals (like \"a\", \"\"\"a\"\"\")\n        Expression.Literal str -\u003e\n            if String.contains \"frits.com\" str then\n                -- Return a single error, describing the problem\n                [ Rule.error\n                    { message = \"Replace `frits.com` by `fruits.com`\"\n                    , details = [ \"This typo has been made and noticed by users too many times. Our company is `fruits.com`, not `frits.com`.\" ]\n                    }\n                    -- This is the location of the problem in the source code\n                    (Node.range node)\n                ]\n\n            else\n                []\n\n        _ -\u003e\n            []\n```\n\nThen add the rule in your configuration:\n\n```elm\nmodule ReviewConfig exposing (config)\n\nimport NoStringWithMisspelledCompanyName\nimport Review.Rule exposing (Rule)\n\n\nconfig : List Rule\nconfig =\n    [ NoStringWithMisspelledCompanyName.rule\n    -- other rules...\n    ]\n```\n\nIf you want to write a rule but might not have an idea of where to start,\nhave a look on the [elm-review-rule-ideas](https://github.com/jfmengels/elm-review-rule-ideas)\nrepository. You may also want to look for rules in the [Elm packages registry](https://package.elm-lang.org/) and in the [GitHub `elm-review` topic](https://github.com/topics/elm-review).\n\n\n## When to write or enable a rule\n\nThe bar to write or enable a rule should be pretty high.\nA new rule can often turn out to be a nuisance to someone, sometimes in ways you didn't predict, so making sure the rule solves a real problem, and that your team is on board with it, is important.\nIf a developer disagrees with a rule, they may try to circumvent it, resulting in code that is even more error prone than the pattern that was originally forbidden.\nSo the value provided by the rule should be much greater than the trouble it causes, and if you find that a rule doesn't live up to this, consider disabling it.\n\nReview rules are most useful when some pattern must never appear in the code.\nIt gets less useful when a pattern is allowed to appear in certain cases, as there is [no good solution for handling exceptions to rules](#is-there-a-way-to-ignore-errors-).\nIf you really need to make exceptions, they must be written in the rule itself, or the rule should be configurable.\n\nFor rules that enforce a certain **coding style**, or suggest simplifications to your code, I would ask you to raise the bar for inclusion even higher.\nA few examples:\n\n  - I much prefer using `|\u003e` over `\u003c|`, and I think using the latter to pipe\n  functions over several lines is harder to read. Even if using `|\u003e` was indeed\n  better for most situations and even if my teammates agree, this would prevent\n  me from writing tests [the suggested way](https://github.com/elm-explorations/test#quick-start)\n  for instance.\n  - If a record contains only one field, then I could suggest not using a record\n  and use the field directly, which would make things simpler. But using a\n  record can have the advantage of being more explicit: `findFiles [] folder` is\n  harder to understand than `findFiles { exceptions = [] } folder`.\n\nSome rules might suggest using advanced techniques to avoid pitfalls, which can make it harder for newcomers to get something done.\nWhen enabling this kind of rule, make sure that the message it gives is helpful enough to unblock users.\n\nWhen wondering whether to enable a rule, I suggest using this checklist:\n  - [ ] I have had problems with the pattern I want to forbid.\n  - [ ] I could not find a way to solve the problem by changing the API of the problematic code or introducing a new API.\n  - [ ] If the rule exists, I have read its documentation and the section about when not to enable the rule, and it doesn't apply to my situation.\n  - [ ] I have thought very hard about what the corner cases could be and what kind of patterns this would forbid that are actually okay, and they are acceptable.\n  - [ ] I think the rule explains well enough how to solve the issue, to make sure beginners are not blocked by it.\n  - [ ] I have communicated with my teammates and they all agree to enforce the rule.\n  - [ ] I am ready to disable the rule if it turns out to be more disturbing than helpful.\n\n## Is there a way to ignore errors?\n\n`elm-review` does not provide a way to disable errors on a case-by-case basis — by line or sections of code —\nlike a lot of static analysis tools do. I've written about this in\n_[How disable comments make static analysis tools worse](https://jfmengels.net/disable-comments/)_.\n\nBecause you can't ignore errors easily, `elm-review` puts more burden on the rules, requiring them to be of higher quality\n— less false positives — and better designed — avoiding rules that will inherently have lots of exceptions or false positives.\n\nIt does provide 2 systems that I think are better alternatives for the health of your project.\n\n### Configuring exceptions\n\nYou can [configure exceptions](https://package.elm-lang.org/packages/jfmengels/elm-review/2.15.1/Review-Rule/#configuring-exceptions),\nwhich consists of marking specific directories or files as not relevant to a rule or set of rules, preventing errors to be reported for those.\n\nIt is a good fit if you wish for `elm-review` to not report errors in vendored or generated code,\nor in files and directories that by the nature of the rule should be exempted.\n\n### Temporarily suppressing errors\n\n`elm-review` has a system to temporarily suppressed errors which aims to help you gradually adopt rules that\nreport many errors in your project without having you fix all the issues beforehand.\n\nRunning `elm-review suppress` will generate one JSON file in `review/suppressed/` (in your review configuration) for\nevery rule that currently reports errors, and records the number of suppressed errors per file in your project.\nThese files should be included in your versioning system.\n\nAs long as suppression files exist for your project, running `elm-review` will behave as usual but with these additional behaviors:\n- Suppressed errors won't be reported.\n- If there are outstanding errors for the ignored rules and files, the related\n  suppressed errors will be reported until you reduce the number of errors\n  back to the number in the JSON file. This is a good opportunity to fix more!\n- If no errors are being reported and there are less suppressed errors than\n  before, suppression files will be updated automatically, in order to make\n  sure no new errors get re-introduced unknowingly.\n\nWhile you can run the `suppress` command to ignore newly reported errors, please do so with moderation. The aim is to\nallow enabling rules while there are errors remaining and to have these fixed incrementally, not to make it easier to\nignore errors.\n\nUse `elm-review suppress --help` to start using this, and read more about the\n[design choices](https://github.com/jfmengels/elm-review/blob/master/documentation/design/suppress.md) that went into\nthe feature.\n\nNote that to avoid uncommitted suppression files in your project's main branch, it is recommended to use\n`elm-review suppress --check-after-tests` at the end of your test suite.\n\n\n## Extract information\n\n`elm-review` has quite a nice way of traversing the files of a project and collecting data, especially when things\naren't as simple as grepping or applying a regex on the code.\n\nWhile the tool is mainly designed around reporting issues, you can also use it to extract information from\nthe codebase. You can use this to gain insight into your codebase, or provide information to other tools to enable\npowerful integrations.\n\nTo make use of this feature, run `elm-review --extract --report=json` with a configuration containing a rule that uses\n[`Rule.withDataExtractor`](https://package.elm-lang.org/packages/jfmengels/elm-review/2.15.1/Review-Rule/#withDataExtractor).\n\nThe result for a rule will be stored under `\u003cjson\u003e.extracts.\u003cYourRuleName\u003e`. To access it, you can then pipe the result\ninto either a `Node.js` script, a tool that expects JSON, or [`jq`](https://stedolan.github.io/jq/) as in the example below.\n\n```bash\nelm-review --extract --report=json |\n    jq -r '.extracts[\"YourRuleName\"]'\n\n# or to be slightly faster\nelm-review --extract --report=json --rules YourRuleName |\n    jq -r '.extracts[\"YourRuleName\"]'\n```\n\nCombine the above out with `--watch` for fast feedback when editing your code!\n\n```bash\nelm-review --report=json --extract\n```\n\nand by reading the value at `\u003coutput\u003e.extracts[\"YourRuleName\"]` in the output.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjfmengels%2Felm-review","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjfmengels%2Felm-review","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjfmengels%2Felm-review/lists"}