All work

An application for a new industry is assembled from configuration, not written again

Screens, data, access rights and processes are described in configuration files. Launching a product for another industry does not mean copying and rewriting code.

The task

Launch applications for different industries — freight forwarding, car servicing — on one base, without copying code.

Solution

Screens, data, access rights and processes are described in configuration files. The interface is assembled from ready blocks — table, form, field, button, tabs, menu — and the same files describe routes, entities, who sees what, data queries and translations.

Simple expressions interpolate data, cast types, format values and check conditions. Configuration is validated against a schema and by a custom validator, so a mistake is found before launch rather than by a user.

Result

157 modules in the base, 60 modules and 218 processes in the industry application, and one more application of 14 modules. A new industry is connected through configuration.

The second use of the same approach

The principle is the same as in the freight accounting system, the task is different: there configuration describes processes, here it describes screens, data and rights.

How it is built

Applications for different industries are assembled from configuration files on one platform coreFreight forwarding60 modules · 218 processesCar service14 modulesA new industryconfiguration files only, no codeConfiguration filesscreens · data · access rights · processes · translations · routesSchema and validatorerrors are caught before launchPlatform core: 157 modulesblocks: table, form, field, button, tabs, menu · expressions · access rightsDataGraphQL queries and mutationsApplications for different industries are assembled from configuration files on one platform coreFreight forwarding60 modules · 218 processesCar service14 modulesA new industryconfiguration files only, no codeConfiguration filesscreens · data · access rightsprocesses · translations · routesSchema and validatorerrors are caught before launchPlatform core: 157 modulesblocks: table, form, field, button, tabs,menuexpressions · access rightsDataGraphQL queries and mutations

Why this way — where the approach hits its limit

Configuration instead of code pays off exactly as long as the task fits the ready blocks. Past that, three boundaries begin, and they are worth knowing in advance.

First — the temptation to keep extending the language. Once conditions appear in the configuration, then loops, then functions, you discover you have written a bad programming language with no debugger and no syntax highlighting. So expressions are deliberately limited to interpolation, type casting, formatting and simple conditions. Anything harder goes into code.

Second — mistakes surface at runtime, not at build time. The compiler will not catch a typo in configuration. Hence a schema for every block, action and column type plus a custom validator: the mistake is found before launch rather than by a user.

Third — readability. A configuration file several hundred lines long stops being simpler than code, and people start copying it instead of reusing it.

The conclusion I take into any project: describe in configuration what genuinely changes often and is changed by people who are not developers. Everything else is cheaper left as code.

Other case studies

Case studies and personal projects