Disclaimer: This post isn't a manifesto against modularity, but rather a description of a temporary approach for solo developers actively using LLM during rapid iteration and prototyping. For production, large teams, and long-term projects, modularity remains the gold standard.


Hello everyone đŸ‘‹

I would like to share my experience (based on my project), or rather advice on why refactoring is your (and AI's) potential bottleneck and how to solve the problem if you are faced with breaking your monolithic 1000-line script into modules.

The Problem

We've all seen this path: a tiny script suddenly balloons to 500 lines. Then comes the moment when, following the advice of seasoned colleagues, we start the "proper refactoring": creating utils/, parsers/, and proliferating __init__.py files. But in an era where our main co-author is an LLM, this beauty becomes a hindrance.

But why is modularity your source of friction?

If your code works in a single file, that's good. But your project grows. The line count increases. You start getting confused. You decide to refactor. You do it manually because you understand that an AI's advice will turn into another "find -> copy -> paste" quest. But suddenly, you realize something is wrong.

  • You have too many files.
  • You realize it’s messy.
  • It’s an illusion of structure.
  • It introduces dependencies.

When Technical Problems Begin

Dependencies

You need to create a file to list global variables. Your project has bloated. Half the files are just importing dependencies. It looks structured from the outside, but it’s internal chaos.

Example: Your script A now depends on the function process_data() from the module utils.helpers.data_cleaner. For this to work, A needs from utils.helpers.data_cleaner import process_data. Now, if you rename data_cleaner to sanitizer, you are forced to change it in a dozen places, whereas in a monolith, you would only need to change def process_data to def sanitize.

Submitting to AI

If you rely heavily on AI assistants for code generation, managing a modular project can become cumbersome. The AI might struggle to keep track of complex dependency graphs, leading to errors in code generation or suggestions that break existing functionality.

Key point: AI is not a project manager. It is an executor. It works best with a complete, self‑contained context — a single file often provides this more reliably than a collection of interconnected modules.

The Monolith as a Solution

If you have one file, it's beneficial for several reasons:

  1. Local dependencies are resolved. You declare everything - classes, functions, variables - in one file.
  2. It's easier to send the AI one file than multiple files.
  3. It's easier for the AI to parse one file than to reason about the availability of local dependencies from specific project directories.

Pitfalls

A single file can be perceived as a problem simply because it gets huge.

  1. You get confused.
  2. You have to use Ctrl+F to jump to a specific class or function.
  3. Others find it hard to understand.

When monolithic design is a bad idea

  1. Teamwork.
  2. Code that will be maintained for a long time.
  3. Projects with clearly defined components (web API, database, data processing).

But these problems have solution.

Use regions. Seriously, it’s simple. It’s fast. It costs you 6-9 extra characters in the code. By using #region and #endregion (alternatives exist in other languages too), you can easily break the code into blocks. For example, you can declare all classes in #region Classes and helper functions in #region Helpers. It’s convenient. Practical. Clean. And with IDE extensions (for example, Region Maker for VScode), it becomes an excellent experience.

Conclusion

The best code is the code that isn't written, but seriously - choose what works best for you. Good luck!