{"id":13568427,"url":"https://github.com/NoahTheDuke/splint","last_synced_at":"2025-04-04T04:31:02.845Z","repository":{"id":102437755,"uuid":"543893156","full_name":"NoahTheDuke/splint","owner":"NoahTheDuke","description":"A Clojure linter focused on style and code shape.","archived":false,"fork":false,"pushed_at":"2025-03-28T20:18:12.000Z","size":1290,"stargazers_count":120,"open_issues_count":6,"forks_count":2,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-03T12:11:10.801Z","etag":null,"topics":["clojure","linter"],"latest_commit_sha":null,"homepage":"https://cljdoc.org/d/io.github.noahtheduke/splint/","language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/NoahTheDuke.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-10-01T04:50:28.000Z","updated_at":"2025-03-28T20:18:15.000Z","dependencies_parsed_at":"2023-11-08T23:22:16.916Z","dependency_job_id":"301e03d3-6910-4ced-9090-846c3ae6c537","html_url":"https://github.com/NoahTheDuke/splint","commit_stats":{"total_commits":495,"total_committers":4,"mean_commits":123.75,"dds":0.0060606060606061,"last_synced_commit":"a466f5766f89e8c69d199cff148df8b1b7fffbce"},"previous_names":[],"tags_count":38,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NoahTheDuke%2Fsplint","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NoahTheDuke%2Fsplint/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NoahTheDuke%2Fsplint/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NoahTheDuke%2Fsplint/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/NoahTheDuke","download_url":"https://codeload.github.com/NoahTheDuke/splint/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246998198,"owners_count":20866694,"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":["clojure","linter"],"created_at":"2024-08-01T14:00:25.702Z","updated_at":"2025-04-04T04:31:02.828Z","avatar_url":"https://github.com/NoahTheDuke.png","language":"Clojure","funding_links":[],"categories":["Clojure","Code Analysis and Linter"],"sub_categories":[],"readme":"\u003c!-- markdownlint-disable-next-line --\u003e\n\u003cimg src=\"images/snake_parens.svg\" alt=\"splint icon\" width=\"200\" align=\"right\"\u003e\n\n# Splint\n\n[![Clojars Project](https://img.shields.io/clojars/v/io.github.noahtheduke/splint.svg)](https://clojars.org/io.github.noahtheduke/splint)\n[![cljdoc badge](https://cljdoc.org/badge/io.github.noahtheduke/splint)](https://cljdoc.org/d/io.github.noahtheduke/splint)\n\n**Splint** is a Clojure linter focused on style and code shape. It aims to warn about many of the guidelines in the [Clojure Style Guide][style guide]. It is inspired by the Ruby linter [RuboCop][rubocop] and the Clojure linter [Kibit][kibit].\n\n[style guide]: https://guide.clojure.style\n\n## Installation and Usage\n\nMore explicit instructions can be found in the [installation][installation], [usage][usage], and [configuration][configuration] pages, but here's a quick rundown:\n\n[installation]: docs/installation.md\n[usage]: docs/usage.md\n[configuration]: docs/configuration.md\n\n### Clojure CLI\n\n```clojure lazytest/skip=true\n:aliases {:splint {:extra-deps {io.github.noahtheduke/splint {:mvn/version \"1.20.0\"}\n                                org.clojure/clojure {:mvn/version \"1.11.1\"}}\n                   :main-opts [\"-m\" \"noahtheduke.splint\"]}}\n```\n\nRun with `clojure -M:splint [args...]`.\n\n### Leiningen\n\nAdd this to `project.clj`:\n\n```clojure lazytest/skip=true\n:profiles {:dev {:dependencies [[io.github.noahtheduke/splint \"1.20.0\"]\n                                [org.clojure/clojure \"1.11.1\"]]}}\n:aliases {\"splint\" [\"run\" \"-m\" \"noahtheduke.splint\"]})\n```\n\nRun with `lein splint [args...]`.\n\n## Rationale\n\nWhy another Clojure linter? We have [clj-kondo][clj-kondo], [eastwood][eastwood], and [kibit][kibit], in addition to [clojure-lsp][clojure-lsp]'s capabilities built on top of clj-kondo. I have contributed to most of these, and recently took over maintenance of kibit. However, most of them aren't built to be easily modifiable, and while kibit's rules are simple, the underlying engine (built on [core.logic][core.logic]) is quite slow. This means that adding or updating the various linting rules can be quite frustrating and taxing.\n\nInspired by [RuboCop][rubocop], I decided to try something new: A \"fast enough\" linting engine based on linting code shape, built to be easily extended.\n\n[clj-kondo]: https://github.com/clj-kondo/clj-kondo\n[eastwood]: https://github.com/jonase/eastwood\n[kibit]: https://github.com/clj-commons/kibit\n[clojure-lsp]: https://clojure-lsp.io\n[core.logic]: https://github.com/clojure/core.logic\n[rubocop]: https://rubocop.org\n\n## Non-goals\n\nFor speed and simplicity, Splint doesn't run any code, it only works on the provided code as text. As such, it doesn't understand macros or perform any macro-expansion (unlike Eastwood) so it can only lint a given macro call, not the resulting code.\n\nclj-kondo performs lexical analysis and can output usage and binding information, such as unused or incorrectly defined vars. At this time, Splint makes no such efforts. It is only focused on code shape, not code intent or meaning.\n\nVersions are not semantic, they are incremental. Splint is not meant to be infrastructure, so don't rely on it like infrastructure; it is a helpful development tool. It should not be relied on as a library. I make no guarantees about public API, visibility of functions, consistency of data shape, or otherwise. I hope to maintain consistent `json` and `edn` output so users can expect that to stay the same, but everything inside of Splint should be considered implementation detail.\n\n## Speed comparison\n\n```text\n$ tokei\n===============================================================================\n Language            Files        Lines         Code     Comments       Blanks\n===============================================================================\n Clojure               172       122744       111266         4421         7057\n ClojureC                4         1013          851           36          126\n ClojureScript          48        14220        13184          142          894\n\n$ time lein kibit\n...\nreal    34m30.395s\nuser    35m4.952s\nsys     0m2.995s\n\n$ time splint .\n...\nLinting took 5622ms, checked 223 files, 804 style warnings\n\nreal    0m5.969s\nuser    0m47.830s\nsys     0m0.379s\n```\n\n## License\n\nCopyright © Noah Bogart\n\nDistributed under the Mozilla Public License version 2.0.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FNoahTheDuke%2Fsplint","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FNoahTheDuke%2Fsplint","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FNoahTheDuke%2Fsplint/lists"}