Introducing gdstyle, a linter and formatter for GDScript
Piero

We’ve spent a long stretch building Bobium Brawlers in Godot 4, and as the codebase grew we noticed something: a real chunk of every code review had nothing to do with the code. It was about style: a snake_case slip, a stray pass, a function ordered below the thing that calls it, a variable named data when it could have said something real.
So we built a small tool to take that off our plate. We’ve used it inside the studio for months, and it’s quietly helped us ship cleaner, more readable, more consistent GDScript ever since. We figured the wider Godot community might get the same mileage out of it, so we’re open-sourcing it as gdstyle.
Why we built it
GDScript already has good tooling, and good conventions behind it. Scony’s gdtoolkit has been the community’s workhorse for years; GDQuest ships a fast GDScript Formatter for Godot 4; and the GDScript style guidelines that Nathan Lovato and GDQuest put together shaped how a lot of us write Godot code in the first place. We’ve leaned on all of it, and gdstyle owes it a debt.
Building Bobium Brawlers, we had a clear picture of the tool we wanted:
- Style tooling should feel like infrastructure. One binary, no runtime, no package manager. It runs the same on a laptop and in a CI container, and it’s fast enough to fire on every save and every commit.
- One tool for the whole loop. Linting, formatting, and auto-fixing behind a single command and a single config file.
- Opinionated out of the box. A tool should arrive with a real point of view, so a team gets consistency from day one without designing a ruleset first.
- It should understand Godot, not just GDScript. A project is scenes and resources too. Rename a signal and the tool should follow it into the
.tscnand.tresfiles that wire it up, so a refactor stays correct project-wide.
That’s the tool we wanted, so we built it.
What gdstyle does
Here’s what that looks like in practice. gdstyle lints, with 52 rules across five categories: naming, formatting, ordering, quality, and syntax. It formats, with a multi-pass formatter that’s idempotent, so running it on already-formatted code changes nothing. And it fixes: most warnings carry an automatic fix, in a safe tier for mechanical changes and an opt-in tier for larger ones like the scene-aware renames.
It’s also fast: gdstyle lints a 108k-line Godot 4 project in ~0.7 s and format-checks it in under 1 s, about 4× faster than GDQuest’s Rust formatter and 10 to 14× faster than the Python gdtoolkit. The rule sets differ (gdstyle has 52 rules, gdlint about 28, GDQuest’s lint 17), and the formatters produce different canonical outputs, so treat this as “each tool doing its own job” rather than a proper benchmark.
How we use it
We run gdstyle in two places.
The first is the editor. A Godot plugin runs it without leaving the engine, including format-on-save, so files are tidy before they’re committed.
The second is CI. Every pull request runs gdstyle check over the whole project, and a new warning turns the build red. We keep a simple zero-new-warnings rule: touch a file, don’t leave it worse. The effect we didn’t expect is that style basically left code review. Reviewers stopped pointing at spacing and went back to the actual logic.
gdstyle check # lint the project
gdstyle fmt # format it
gdstyle check --fix # apply the safe autofixes
Opinionated, but yours to tune
gdstyle is opinionated: the defaults follow the conventions the Godot community already shares, so you get useful results without writing a config first. When you need to, a gdstyle.toml lets you change a rule’s severity, switch one off, or adjust limits like maximum line length.
Open source
gdstyle is MIT-licensed and on GitHub. Every release ships prebuilt binaries for Linux, macOS (Intel and Apple Silicon), and Windows, plus the Godot editor plugin. Before this release we ran it across more than 30 open-source Godot projects to shake out false positives.
The rules reflect what’s worked for one studio. If a rule feels wrong, too aggressive, or missing, open an issue and tell us why. Rule suggestions and pull requests are welcome, and so are reports of where it gets your code wrong.
Repo: github.com/atelico/gdstyle
Give it a run, and let us know how it goes.