Applications that perform the same tasks they did years ago are now several times larger. The growth comes from how software is assembled rather than from what it does.

Dependencies bring their own dependencies

Adding a library to save a week of work is almost always the right decision individually. Each library brings the libraries it depends on, and those bring more.

The resulting tree can be hundreds of packages deep for a modest application, and much of it is included to support cases the application never encounters.

Tools that strip unused code help, but they can only remove what they can prove is unreachable. Dynamic behaviour defeats that analysis and forces the code to be kept.

One app now ships several builds

Devices differ in processor architecture, screen density and platform version, and an application built to run on all of them may include separate compiled code and separate assets for each.

Distribution systems can deliver only the relevant portion, which is why the installed size is often much smaller than the uploaded package.

Where that splitting is not used, every user downloads variants they will never run, and the difference can be a substantial share of the total.

Assets outgrow code quickly

Images, fonts, sounds and video occupy far more space than logic. Higher resolution screens require larger assets, and supporting several densities multiplies them again.

Localisation adds further copies of text and sometimes of images containing text, so a broad language range expands the package without changing behaviour.

Because assets are easy to add and awkward to audit, unused ones tend to remain in the package long after the screens that referenced them were removed.

Embedded runtimes add a floor

Applications built with cross-platform frameworks bundle a rendering engine or runtime, which sets a minimum size before any application code is included.

That floor buys development speed and consistent behaviour across platforms, and for most teams the trade is deliberate rather than accidental.

Nothing creates pressure to shrink

Storage and connection speeds improved enough that size stopped being an obvious constraint, so no one is measured on it and it drifts upward unopposed.

The cost surfaces indirectly instead: slower installation, longer updates and users on limited connections or older devices quietly falling out of the addressable audience.

Teams that do measure size typically find large reductions available immediately, which indicates the growth was inattention rather than necessity.