When building Convertim, one of the early technical decisions was how different workflows should be supported. Some users prefer opening an application, dragging a few files, choosing an output format and pressing a button. Others prefer running commands, automating repetitive tasks or integrating tools into existing workflows.
Both approaches solve the same problem, but they represent different ways of interacting with software. The challenge was deciding whether those workflows should become separate tools or different ways to use the same application.
The initial decision
A common solution would have been creating two independent tools: a desktop application focused on visual interaction and a command-line tool focused on automation. This approach works well in many projects because each tool can evolve independently and focus on a specific type of user.
While designing Convertim, we looked at it from a different perspective. Were we actually building two different products, or were we creating two different ways to access the same functionality?
That question influenced the internal architecture. Instead of treating the graphical interface and the command line as separate projects, we decided to keep them as different entry points connected to the same core.
Separating interface from logic
One of the most important ideas behind this decision was separating the user interface from the actual processing logic. The conversion engine, file handling, validation and configuration should not depend on whether someone interacts with the application visually or through a terminal.
The graphical interface and the command line are simply different layers built around the same foundation. They receive different types of input, but the core responsible for processing those actions remains shared.
This separation means improvements made internally benefit both workflows. Changes to conversion logic, optimizations or bug fixes do not need to be implemented multiple times because both experiences rely on the same underlying system.
Avoiding duplicated implementations
Duplicating functionality can sometimes feel like the fastest solution, especially during the early stages of a project. Creating a separate CLI implementation alongside the desktop application would probably have worked initially.
The problem usually appears later, when both versions need to evolve. A bug fixed in one implementation needs to be fixed again somewhere else. A new option has to be added twice. Small differences slowly appear between tools that are expected to behave consistently.
Keeping a shared foundation helps reduce those problems. Not because having less code automatically means having better software, but because reducing duplicated logic usually makes a project easier to maintain over time.
Supporting different workflows
A graphical interface works well when direct interaction is the goal. Opening an application, selecting files and visually adjusting options can be the fastest and most comfortable experience for many users.
But not every workflow works that way. Some tasks are repetitive by nature. Some users need to process many files frequently or include conversion steps inside scripts and automated processes.
In those situations, forcing every interaction through a graphical interface creates unnecessary friction. The goal of adding CLI support was not to replace the GUI, but to provide another way to interact with the same tool depending on the context.
Sometimes clicking a button is the best experience. Sometimes running a command is.
The technical trade-offs
Keeping GUI and CLI together also introduces some challenges. A shared foundation requires clearer boundaries between different parts of the application because multiple interfaces depend on the same internal behavior.
Features need to be designed considering more than one interaction model. A change is not only a visual decision anymore; it can affect both manual and automated workflows.
Like most engineering decisions, this approach is a trade-off. Separate applications provide more independence, while a shared core provides more consistency and reduces duplicated work.
There is no universal answer. The right decision depends on the goals and constraints of each project.
Building around workflows
For Convertim, keeping GUI and CLI inside the same application was not about adding another feature. It was about designing the application around the idea that different users can have different workflows without needing completely different tools.
The visible part of software is usually the interface, but many of the decisions that define the experience happen much deeper in the architecture.
Good architecture often stays invisible.
And that usually means it is doing its job.
Top comments (0)