Software development is expensive. It can take a team of developers thousands of collective hours to build, test, and deploy an application to the market. Naturally, software vendors aim to reduce these costs in any way they can. A common approach is to “build an application that builds applications”, usually by allowing users to drag-and-drop controls onto screens and wire them up with predefined logic elements, API calls, etc. Almost without exception, this becomes a money pit for the vendor.
Fortunately, there are ways of reducing development costs and speeding up production.
Application builder projects seek to take advantage of the concept of reusability. Reusability is king when it comes to writing software efficiently. One of the most repeated mantras of software development is DRY (Don’t Repeat Yourself). If a component appears multiple times in an application (or across multiple applications), write a generic version of it once and use parameters to customize it wherever you need to use it.
Reusability is ultimately about abstraction: instead of hand-coding all the nitty gritty details of every piece of a program, write components that embody the higher-level concepts of each piece of functionality, then combine them. This is usually done in code, but application builders are an attempt to create even higher level abstractions in the form of drag-and-drop components that can be used to assemble an application as if out of LEGO bricks. A common goal is to eliminate the need to hand-write any code at all.
Bugs are expensive. Not only can they be a source of embarrassment for you (the vendor), they can also be a source of lost business, and in the worst cases, dangerous. Nobody wants to be examined by a radiation therapy machine that occasionally moonlights as a microwave oven, and nobody wants to be the sorry soul who programmed it.
Wouldn’t it be great if you could assemble new software from pre-made, proven components? Even better, if you could just drag them into a flowchart that was understandable by anyone and would make logic errors obvious to even an untrained eye?
Hand-coding is time consuming, and to non-developers, the resulting code is as opaque as the windows of a meth lab, making management dependent on the (expensive) expertise of their engineers. But flowcharts, diagrams, and drag-and-drop interfaces are self-explanatory. Technical expertise would be unnecessary if such tools could be used to build a complete application.
The principles of reusability are best applied to small components and overall architectures, not all the stuff in between. It makes sense to write a generic textbox that can be used to create a light-colored textbox in one application and a dark, numbers-only textbox in another. It also makes sense to create a microservice framework that can be used to construct multiple backends that do vastly different things.
It almost never makes sense to write a handful of generic “screens” and try to implement every application thereafter with them. You may laugh, but that’s a real assignment I’ve been given: seven different types of screens to cover the entirety of all possible applications.
The fatal flaw of application builders is that they’re based on the idea that one can get away from having to write code. Just as software frameworks create useful abstractions of architectures, freeing the developer from having to write them, application builders aim to create an abstraction of the entire idea of applications in general, freeing the developer from having to write any code.
Programming languages are designed to be as easy as possible to use. Productivity is always an important goal when designing a language, and languages that don’t pay heed to it don’t become mainstream. And yet they express only low-level concepts. Why? Why is such a painful level of detail necessary to write a computer program?
The benefit of abstractions is that they allow you to think in terms of large, high-level concepts without being distracted by details. But that’s also their greatest weakness: they remove your ability to be concerned with details. And that’s why attempting to eliminate coding fails: if you need to customize your abstraction in an unexpected or unusual way, without code, you’re crippled. Programming languages are low-level because that’s the level of detail needed to write programs.
Of course, you could create an application that allows you to drag and drop logic “elements” onto a flowchart and express the same level of detail afforded by a programming language. But then what do you have? A programming language–one that’s encumbered by the overhead of dragging and dropping instead of typing.
Consider the goal of an application builder–making developers obsolete. Most developers are well aware that part of their job is to automate themselves out of it, and we find that perfectly acceptable. And most businesses that depend on us are happy to help, which is why they so commonly undertake application builder projects.
Given the popularity of this goal, what would happen if someone created an application builder that achieved it? To say that their product would be in high demand would be a gross understatement. They would turn the software industry on its head. I don’t think it’s hyperbole to say that they would amass riches rivaling those of Bill Gates and Mark Zuckerberg, and be famous the world over.
The fact that none of this has come to pass in spite of so many (probably thousands) of attempts is evidence that a useful, general-purpose application builder is incredibly difficult, if not impossible, to build. I would argue that such a thing is most definitely impossible, because the idea is fundamentally flawed.
The goal of reducing development and testing costs by reusing pre-made components instead of rewriting them for every project is not at all unreasonable. On the contrary, it’s a principle of good software engineering. Fortunately, there are effective and proven ways of doing this that don’t involve drag-and-drop application builders.
Maybe your shop writes a specific kind of application. Let’s say you write software for kiosks, which tends to be characterized by simple workflow- or wizard-based user interfaces that interact with peripheral hardware. For you, it might make sense to build a GUI framework that facilitates building these types of interfaces, with built-in support for high level concepts like workflows.
Or maybe you write custom web frontends for online banking. You could build GUI components that handle lists of transactions, two-factor authentication, gathering account or credit card information, etc. These things tend to be similar across banking applications, so they’re good candidates for reusability.
I concede that there are a few use cases where application builders make sense. One such case is GameSalad. This niche is unique because:
It’s targeted at a market that accepts its limitations. People who want to build a simple video game using something like GameSalad are typically not concerned with being able to use the latest custom-coded AI algorithms. As a vendor, telling your potential customers “we can’t/won’t implement that feature because our application builder doesn’t support it” would certainly cause them to take their business elsewhere.
Applications built with it are closed systems. They don’t (to my knowledge) interact with third-party APIs. A major difficulty in using an application builder to create custom software for individual customers is that they may have pre-existing APIs with which the application is expected to interact. These APIs often have non-standard behaviors (i.e., using custom error codes) that can only be properly dealt with through the precise logic of code.
If your business occupies a niche that meets those requirements, an application builder may make sense. That said, it’s still a risky proposition given the sheer scope that such projects usually attain. If you accept the risk, I suggest you start by building a framework as previously described. Make sure it can be used to efficiently build your target applications by itself, with code. Then, design an application builder on top of it that uses the framework as a basis for the end products. The application builder can generate files that describe the application’s behavior, and those files can be consumed by a runtime that “wires up” the framework accordingly.
Building a framework first will help you hash out the concepts that the application builder needs to embody. It will also make the builder easier to write because, hey, you have a framework to work with. And if worse comes to worse and the application builder project fails, all is not lost. You still have the framework.