Why robots should format our code for us
As developers, we know that writing code is only part of the job. To keep our codebases maintainable, scalable, and accessible to other developers, we also need to ensure our code is clean, readable, and consistently formatted. However, code formatting is often seen as a tedious chore that takes up valuable time that could be spent writing more code.
While many developers take pride in their personal code styling, having a consistent code style across a project‘s entire codebase is much more important than any individual‘s preferences. Inconsistent formatting makes code harder to read, understand, and maintain, especially for developers who are new to a project. It can also lead to wasted time spent arguing over trivial formatting decisions in code reviews.
The solution to these problems is to take the burden of code formatting off of human developers entirely and outsource it to the machines. Code formatting tools and linters can automatically restructure and restyle our code according to whatever predefined rules and conventions we decide upon for our team and project.
The problem with manual code formatting
All developers know that reading messy, inconsistently styled code is a pain. It makes the code harder to visually parse and understand, slows down code reviews, and can even introduce bugs from misinterpreted logic.
So most developers try their best to keep their code neat and formatted according to some set of style guides and best practices, such as using consistent indentation, line breaks, naming conventions, etc.
The problem is that manually formatting code is time-consuming, error-prone, and difficult to keep consistent across an entire project, especially when multiple developers are involved. Even if a project has a defined code style guide, it‘s still on each individual developer to remember and adhere to all of the rules while they‘re busy trying to write functioning code.
Inevitably, small inconsistencies and individual preferences will creep in. One developer may prefer tabs while another uses spaces. Or maybe someone accidentally let their editor auto-format a file to different rules. Fixing these small formatting discrepancies then becomes a constant game of whack-a-mole during code reviews.
And even if nitpicky formatting issues are caught by reviewers, that means time wasted on back-and-forth discussion and rework over something as trivial as whether there should be a space before or after a curly brace. Multiply this wasted effort across every Pull Request and every developer and it starts to add up to a lot of lost productivity.
The benefits of consistent code style
While each individual developer having their own preferred code style is natural, the benefits of maintaining a single consistent style across a project are numerous:
-
Consistent code is easier to read and understand, even if you‘re new to the project. Unfamiliar things like inconsistent indentation or irregular naming stick out to readers.
-
It‘s easier to spot actual logic errors when you‘re not distracted by arbitrary stylistic differences everywhere. Diffs and PRs become much more useful when they only highlight meaningful changes.
-
Onboarding new developers is much smoother when they don‘t have to try to imitate each existing developer‘s individual style or try to pick up unwritten rules from reading the codebase.
-
Eliminates bikeshedding and unproductive arguments over stylistic preferences. Standardizing on an agreed-upon set of rules keeps discussion focused on the code logic itself.
-
Looks more professional and implies that the project is actively maintained according to engineering best practices and standards.
Of course, trying to get a team of developers to all follow the same exact rules manually would be almost impossible, not to mention a huge waste of time and mental energy. That‘s where code formatters come to the rescue.
Introducing code formatters
Code formatters are tools that automatically restructure your source code files according to configurable formatting rules and style guides. They essentially act like a code review bot that instantly reformats your code to match the project‘s predefined conventions every time you hit save.
The beauty of code formatters is that they take all of the guesswork and manual effort out of styling your code. No more having to memorize style guides or waste time adjusting whitespace. Just write your code however you want, and let the formatter clean it up for you according to the rules.
Code formatters will automatically handle details like:
- Indentation levels and styles (tabs vs spaces)
- Line lengths and wrapping
- Spaces around operators and brackets
- Blank line placement
- Import statement ordering
- Enforcing naming conventions
- Removing unused imports
And unlike a human reviewer, code formatters never get tired, miss things, or argue about which style is best. They‘ll apply the same consistent rules every time.
How code formatters work
Most code formatters work by parsing your source code into an Abstract Syntax Tree (AST), applying formatting transformations to the tree according to rules, and then regenerating the formatted source code from the modified AST.
The formatter rules are usually highly configurable and can be set on a per-project basis by a config file committed with the project source code. Many formatters come with sensible defaults and presets for popular style guides. Teams can also usually override individual rules to match their agreed-upon conventions.
Developers can run code formatters either manually via a CLI or code editor plugin, or by setting them up to run automatically using Git hooks, checks in the build pipeline, or at scheduled intervals.
Popular code formatters for different languages
There are many great open source and commercial code formatters available for every popular programming language. Here are a few of the most widely used:
- Prettier – Opinionated JavaScript/TypeScript/CSS/HTML/JSON formatter
- Black – "Uncompromising" code formatter for Python
- ClangFormat – Formatter for C/C++/Objective-C based on Clang
- google-java-format – Java formatter based on Google‘s style guide
- ktlint – Kotlin style guide and linter/formatter
- rustfmt – Rust code formatting tool
Many code editors like VS Code also have built-in formatting and linting functionality, or support plugins for hooking up your preferred external tools.
Setting up a code formatter in your project
To take advantage of automatic formatting in your project, you‘ll first need to decide on which formatter to use and what conventions and rules to follow. It‘s a good idea to have a team discussion to get buy-in and surface any major disagreements before settling on an approach.
Most formatters can be installed via your language‘s package manager (npm, pip, cargo, etc.) or downloaded as a standalone binary. You‘ll then need to create a config file to enable/disable/customize the various formatting rules to your liking.
Here‘s an example .prettierrc config file for Prettier:
{
"printWidth": 100,
"tabWidth": 2,
"useTabs": false,
"semi": true,
"singleQuote": true,
"trailingComma": "es5",
"bracketSpacing": false,
"arrowParens": "avoid"
}
Config files can usually be committed to your project‘s repo so that the formatting is always consistent across all developers‘ machines.
It‘s a good idea to also add an npm script or Makefile target as a shortcut for running the formatter over your entire codebase. For example:
{
"scripts": {
"format": "prettier --write ."
}
}
Integrating code formatters into your workflow
Code formatters are most useful when they‘re integrated into your development workflow so that they run frequently and automatically.
Some ideas for integration points:
- Configure your code editor to automatically run the formatter every time you save a file
- Set up a pre-commit Git hook to format all staged files
- Make your CI build fail if unformatted code is detected
- Add the formatter –check mode to your test suite
You‘ll also want to ensure that all of your developers have the formatter installed and configured identically via the previously mentioned config file.
At first, it may feel slightly awkward to give up some control over your code styling, but after using a formatter for a while most developers appreciate never having to think about trivial stylistic decisions again.
Downsides and limitations of code formatters
As amazing and time-saving as code formatters are, there are a few potential downsides and limitations to be aware of:
Code formatters aren‘t magic – they‘re just applying a predefined set of rules, so there will always be some edge cases they can‘t handle well or won‘t match your preferred style 100%. Usually these small inconsistencies are worth the overall time saved.
Some developers may find the lack of control frustrating at first and push back on adopting a formatter. Choosing a more configurable formatter with a well-defined style guide can help alleviate this.
Introducing a code formatter to an existing large codebase for the first time can be disruptive, as it may reformat nearly every file at once. Applying formatting changes gradually and ensuring everyone has the formatter configured before merging is recommended.
If using a newer or less popular formatter, you may run into buggy behavior, poor performance on large codebases, or frequent major version changes that break configs. Sticking to well-established, actively maintained formatters is the safest choice.
The future of code formatting
As programming languages and developer tools continue to evolve, so will our methods for ensuring clean, maintainable, and consistent code.
GitHub Copilot and other AI code generation tools are already starting to automatically write well-styled code (according to the code formatters they were trained on) from natural language inputs. This will likely further reduce the need for developers to ever worry about code formatting directly.
We may even start to see machine learning-based formatters that can learn a project‘s style from existing code and automatically suggest formatting improvements. ML formatters could detect antipatterns and hard-to-read formatting that follows the letter of the style guide but not the spirit.
Regardless of the specific tools, the general trend in software development has been an increasing focus on automating as many of the tedious, unproductive parts of writing software as possible. Just as we now rely on compilers, tests, and CI to find many of our errors for us, in the future we‘ll likely also depend on AI tools to clean up our code styling messes and allow us to focus on more creative and high-leverage work.
Conclusion
Poor, inconsistent code formatting is one of the easiest ways for codebases to become difficult to maintain and contribute to over time, even if the underlying architecture is solid.
But keeping code consistently styled across teams and projects is a constant challenge when left up to error-prone humans. Automating code formatting using tools that instantly apply pre-defined style rules every time code is written is a simple way to maintain consistently clean and readable code without wasting developer time and energy.
Although code formatters may feel slightly restrictive to developers who are used to having full stylistic control, the overall productivity and maintainability benefits to using them are hard to ignore. Once code formatting is just another automated step in your development workflow, you‘ll never want to go back to cleaning up messy spacing and indentation by hand again.