Repo Review 1.0

I’ve just released repo-review 1.0 with a huge update to the WebApp, along with some other solid improvements in speed, simplicity, and stability. Repo-review’s two most popular plugins, sp-repo-review and validate-pyproject, can take full advantage of the new asynchronous fetching mechanism. And if you use the upcoming Python 3.15, the CLI is more responsive than ever thanks to lazy loading!

Speed

Repo-review 1.0 is now faster than ever. It is more careful not to load files multiple times over the network. There’s a new logger in repo-review (accessible from the command line with --log-level), and this reports URL fetches and timing. This was used to discover and fix a multiple load of pyproject.toml.

This was found on the way to a major new feature of repo-review 1.0: asynchronous prefetching. This was developed primarily to keep the webapp more responsive, but it is also available for Python 3.11+ in command line mode if you include the [async] extra (requires httpx to be installed). Plugins report files they know they will need using a new entry point, and then repo-review fetches all of them asynchronously in parallel.

Repo-review 1.0 also supports lazy loading, thanks to flake8-lazy, which I presented previously. uvx flake8-lazy --apply src/**/*.py automagically makes everything lazy that can be lazy. I did a bit of touchup; __main__.py uses absolute imports now, and I’m using the TYPE_CHECKING=False trick to avoid loading typing.

Simplicity and stability

I wanted to add color to the docs cli page, and found that rich-click was broken (again). I’ve seen almost every click app I’ve worked on broken by click at least once (sometimes via typer or rich-click, and often breakage has happened in patch releases), so I used copilot to rewrite the CLI into argparse. With the new Python 3.14 color, it looks great, removes several dependencies, and can no longer be broken by click updates.

IMO, click is good if you need pipelines, but for everything else, you’ll be a lot more reliable if you use argparse (or plumbum.cli). And now it’s really easy to convert, that’s something AI is really good at.

I’ve also removed the requirement that a branch be passed when using the CLI and remote repositories, so now just repo-review gh:org/name works, and uses HEAD.

I’ve also moved to using static versioning, with bump-my-version, instead of dynamic versioning, which fixes an issue when using pre-commit not being able to get the version.

Lots of internal updates as well, like lots more Ruff checks and Zizmor used for better CI security.

WebApp

The biggest change in 1.0 is a re-worked webapp. I did the Advent of Code 2025 in TypeScript specifically to learn how to properly write a webapp for repo-review. Then AI got ridiculously better in the last three months and basically made that pointless, because it knows more about TypeScript than I do. (Really, comparing December 2025 and March 2026, it’s unbelievable how much better it is).

I reworked the webapp into a proper module with a build system, using Bun, making it production ready. It gets rendered into a .min.js file that is attached to our GitHub Releases. It’s in multiple files (split up by AI), and fully typed (strict) and linted.

The webapp now uses the async loading feature to keep the interface responsive for longer. You can see the loading bars and progress reports go (hopefully fly!) by.

There’s a new available checks list when the app loads. The about information is in a distinct box that folds up when you get results. The interface now looks better on mobile or narrow screens.

More CLI features are now available in the webapp. You can select what to show; all checks is the default, but you can also just see errors or errors and skips (--show in CLI). You can copy the results as HTML to copy into a GitHub issue or pull request (--format html in the CLI).

We also now embed the webapp into our own documentation, too.

Other recent features

In 0.12, we added optional reasons for ignores. For example:

[tool.repo-review.ignore]
A = "Skipping this whole family"
B101 = "Skipping this specific check"
C101 = ""  # Hidden from report, like a normal ignore

These will show up in the report with the given reason.

0.12 also added --extend-select and --extend-ignore, so you can add additional items on the command line to combine with static config.

The future

There’s still more that can be done with the webapp; I’d like to add the sub-path option that is available on the command line to support monorepos. I’ve also been looking at using a web worker for Pyodide.

Try it out, and let us know if you have developed a new plugin for it! I’d love to see other languages or other situations (like an “application” focused plugin). We could add a plugin selection system to the webapp in the future.