← Blog

Code quality: what it means for business and how to ensure it

Translated automatically from Russian. Read the original →

For the client, code quality is not a matter of the programmer’s taste. It is money: how much it costs to add a feature, how quickly a bug can be found and fixed, whether the project can be handed over to another engineer. Bad code works only until the first change, and then each edit becomes more expensive than the previous one. I explain how I ensure quality and what you get for it. The overall process is described in the article Software development from scratch turnkey: from idea to release.

What quality code is

This is code that:

  1. Works correctly and this is confirmed by checks.
  2. Is readable by another person without the author’s help.
  3. Is easy to change: an edit in one place does not break five others.
  4. Is secure: takes into account Secure software development: how protection is built in from day one.
  5. Works predictably under load and in abnormal situations.

Why this affects the cost of ownership

The first version of a system usually costs less than the next ten years of its life. If the code is tangled, expenses grow:

SymptomConsequence for the business
No one understands how it worksAny edit carries risk and costs more
No testsEvery release is a lottery, users find the bugs
Everything is connected to everythingA new feature requires reworking the old ones
Knowledge is in one person’s headDependence on a specific contractor
Technical debt has accumulatedDevelopment speed declines over time

My task is to keep the cost-of-change curve flat rather than letting it take off over time.

Practices I apply

Architecture and module boundaries

Quality begins with Software architecture: design and planning before the first line of code. If the system is divided into modules with clear boundaries and responsibilities, the code is easier to understand and change. I hide external dependencies behind interfaces.

Strict typing

I choose languages and settings that catch errors before launch. In Rust, Java, and TypeScript, the compiler cuts off entire classes of problems. For example, the sqlx library in Rust can verify SQL queries against the database schema at build time. The more errors are found by the compiler, the fewer remain for production.

Unified style and automatic checks

Style is not discussed in review — it is applied by tools: formatters (for example, Prettier, rustfmt) and linters (clippy, ESLint). This saves time and removes arguments. I introduce code style from the start of a project, as I did on FlameApp.

Code review

Every change is reviewed before merging. In review I look not only at “does it work,” but also at:

When I work with a team, review is part of training newcomers. How I built this process as a team lead is described in the projects Tezish and FlameApp.

Automated tests

Tests are insurance against breakage as the system evolves. I write tests at different levels: unit tests for logic, integration tests for integration with the database and external services, and end-to-end tests for key scenarios. Details are in the article Тестирование и приёмка ПО: как убедиться, что система работает до релиза.

Continuous integration

Every change is automatically built, checked by linters, and run through tests. If the check fails, the change will not get into the main branch. I set up the pipeline on GitHub Actions, in particular, on the project FlameApp.

Documentation and recorded decisions

Code answers the question “how,” while documentation answers “why.” Key architectural decisions are recorded in short ADRs, and each module has a description of its purpose. The documentation is small but up to date.

Technical debt control

Technical debt is inevitable, but it must be managed. I record conscious compromises: what was simplified, why, and when to return to it. This distinguishes debt from negligence. Part of the time in the plan is allocated to refactoring so that the system does not age faster than it evolves.

How to measure quality

Subjective “I like it” is not enough. I look at:

  • the share of code covered by tests in critical parts;
  • build time and check run time;
  • the number of comments in review and recurring problems;
  • the number of defects that reached users;
  • the time needed for a new person to understand the project and make their first change.

What the client gets

  • Source code that can be handed over to another engineer or team.
  • Automatic checks running in your infrastructure.
  • Documentation and recorded architectural decisions.
  • Predictable cost of further changes.

Need an audit or code you are not ashamed to own?

If you have an existing system, I can conduct a code audit: find problem areas, assess technical debt, and propose an improvement plan. If you are just starting, we will build in quality from scratch. Write to me: Telegram @w1shmaster.

← All posts