There are many factors that contribute to the difficulty of development and maintenance of software. One factor is something that I call software extent. Software extent is a measure of compatibility with different versions of dependencies.
- runtime dependencies
- libraries that are loaded dynamically as well as those that are compiled into the software, including standard libraries
- the runtime of high-level languages
- the runtime included in an executable
- the virtual machine for the language
- the interpreter and/or JIT compiler for the language
- external software that is accessed via an API, including network and filesystem APIs
- operating systems, perhaps of various architectures
- build-time dependencies
- software used to build the project, including compilers and build tools
Software that is made to work with a wide range of dependency versions has large extent. Maintaining compatibility with a wide range of dependency versions makes the project more difficult in a number of ways. In some cases, developers must write code to adapt to incompatible APIs. In some cases, developers must use an older version of a dependency. In some cases, developers are restricted to use of features that are common across systems. The positive aspects are external: the software can be used in a wide variety of environments. A library with large extent helps others avoid dependency hell.
Software that is made to work with a narrow range of dependency versions has small extent. Since developers do not have to worry as much about maintaining compatibility, the software is easier to develop and maintain, as the code is more straightforward. The negative aspects are external: it can be difficult (or impossible) for others to make the software work in environments that the software was not tested with. A library with small extent can cause dependency hell.
Software that is not tested with different dependency versions at all has minimal extent. This is common for private/proprietary software where there is full control over where the software will be used.
When designing software, the degree of compatibility to target depends on the project requirements. When working on private software where there is full control over few environments where the software is used, maintaining compatibility may be considered unnecessary work. When developing open source software, a large extent may be desired in order to make the software easier to use in various environments.