Horizon

The Age of Install-less Apps

By makemind · Jan 8, 2026
This piece has an evidence version. The same subject was made again, with running code and screens that were actually rendered — Only the Screen Thaws — Install-less Apps, and What Compiling Froze. This one is left as it was written.

What it takes to change one button color

Say you fixed one thing. You changed a button color, caught a typo, corrected one line of faulty calculation logic. The diff is about five lines. The work itself takes ten minutes.

Now picture what happens before that ten-minute fix reaches a user's screen.

First you build. You recompile the entire app. Then you package and sign it. You upload it to the store. You wait for review — a day if you're lucky, two or three more often. If it's rejected, you read the reason, fix it, and resubmit. Once approved, the rollout begins. And even then it isn't over. A large share of users stay on the old version for a while. The ones who turned off auto-update, the ones waiting for Wi-Fi, the ones who simply dismissed the update prompt. That typo you fixed reaches users gradually — over days, sometimes weeks.

All of this, to change one button color. And for decades we have accepted it as a natural cost. Whether mobile app or desktop program, between "I fixed it" and "the user sees it fixed" there has always been this long chain.

A screen in the hand — the apps we hold and use every day, with a long chain always behind them
A screen in the hand — the apps we hold and use every day, with a long chain always behind them

This piece is about why that chain exists, how we got trapped in it, and why it was never inevitable. It will be a long read. As the first article of our inaugural volume, we want to make plain where this magazine stands.

How we got trapped in this chain

The chain was not there from the start. Let us trace a short genealogy. If we know where today's frustration hardened, it becomes clear what we need to undo.

First generation — packaged software. The era when programs were sold on CDs or floppy disks. Screen and logic alike were installed entirely onto the user's computer. To fix something? You pressed a new version, redistributed it, and the user had to reinstall. Updates came once a quarter, in the unlucky case once a year. The archetype of the chain was born here — the body of the program lives on the user's device.

Second generation — the web. The browser changed everything. The server sent the screen down, and the browser merely drew it. Fix something? The next visitor instantly sees the new screen. No install, no update. It was the first moment the chain was broken. We were free — as long as we were dealing with documents.

Third generation — the app store. When the smartphone arrived, the current reversed. Camera, GPS, push notifications, accelerometer, offline operation, smooth sixty-frame animation — for the native capabilities the web could not give, we returned once more to apps installed onto the device. And this time another layer was added: the gateway of the store, and review. The chain hardened again, now longer than in the first generation.

Here is the crux to see. The reason we returned to the app-store model was native capability, not because we wanted the chain of install, review, and update. The chain was a cost that came along, unavoidably, in order to gain the capability. Yet somewhere along the way we came to treat that cost as bundled with the capability. "If you want native capability, you must accept the chain too."

What this piece questions is exactly that bundle.

Are capability and chain really inseparable?

The workarounds we have already tried

The industry did not simply endure this chain. Attempts to route around it kept coming, and looking at the successes and limits of those attempts reveals the outline of the real solution.

Hybrid apps (the webview). Put a browser inside an app shell and draw the screen with the web. Because the screen could be changed from the server, the chain was partly broken. But the price was high — the webview was not as smooth as native, it struggled to reach the device's deep features, and it left an awkward "web-like app" feel. In effect, it bought immediacy by giving up some capability.

Code push (hot update). A method that pushes a JavaScript bundle onto the device without going through review, updating the app's logic. It was useful for urgent fixes, but in essence it was still planting code on the device. It had to play tug-of-war with store policy, and large changes ultimately had to return to formal review. It did not break the chain — it merely loosened it.

Server-driven UI (SDUI). A method large services have quietly used. The server sends down the screen's composition — which cards, in which order, with which data — and the app receives that specification and draws it with native widgets. It showed its strength in areas that change often, like feeds and home screens. This is the attempt closest to the essence — draw with native, but let the server decide what to draw.

Yet SDUI too had a ceiling. It was usually a closed system each company built only for its own service. A specification that worked only in that company's app, a structure that spoke only to that company's server. It was not a universal standard. So "our feed screen is defined by the server" became possible, but "define a screen and tools and send them to any server, any device" did not.

This is as far as the industry got. Immediacy was shown by the web, capability by native, dynamic screen definition by SDUI — each separately. It was only that the three were never fused into one open standard.

Why apps had to be "installed" — looking at the structure

Now let us return to the fundamental question. A question so obvious that no one asks it. Why must an app be installed onto the user's device?

The answer emerges when you look at what an app is made of. An app is two things. One is what to show (the screen, the layout, the position and color of buttons), the other is what to do (what happens when a button is pressed, the rules for handling data). A traditional app writes both of these as code and plants them on the device. The screen is code, the behavior is code. The result of compiling that lump of code is exactly the "app that gets installed."

So when anything changes — screen or behavior — that lump of code planted inside the device must be swapped out wholesale. There is no good way to change only a part. That is the root of the build–review–install–update chain. The chain exists not because of laziness or outdated habit, but inevitably out of the structure that "the body of the app lives inside the device."

A deep assumption underlies this structure: the device must be smart. How to draw the screen, what to do when a button is pressed, what to show next — every one of those judgments must be made by code inside the device. So all that judging code is loaded onto the device in advance.

But — what happens if we invert this assumption?

Inverting the premise: what if the server defines the screen

Imagine it this way. The screen and behavior are defined not by the device but by the server. The device no longer knows on its own "what to show." Instead it asks the server — "what should I draw on this screen right now?" When the server answers "one title, one button beneath it, and when the button is pressed this behavior," the device merely draws as instructed.

This small inversion topples the entire chain.

The device no longer holds "code unique to this app." All that lives on the device is a single general-purpose drawing engine that can render whatever comes. Need the screen to change? Edit the server's definition. Need a new feature? Add the behavior to the server. There is nothing to touch on the device. Nothing to build, nothing to submit for review, nothing to install or update — because there is no "app" inside the device to change in the first place.

How does this differ from the workarounds in the previous section? Hybrid gave up native capability, but here the side that draws is a true native runtime, so capability is not given up. Code push still planted code on the device, but here there is no per-app code on the device at all. SDUI was one company's closed system, but what we aim for here is an open standard — define a screen and tools in an agreed-upon way and send them from any server, and the general-purpose runtime of any device draws them.

This "agreed-upon way" is the heart of it. Server and device must speak the same language. A common protocol for what is called a screen, how a tool is called, and what shape data is exchanged in. Only when this protocol is not locked inside one company but kept open does "every server can become an app" hold. (Exactly what this protocol looks like in concrete terms is something this magazine's coding and protocol series will peel back, layer by layer.)

One scene

It will sound abstract, so let us paint a scene.

Suppose the server holds a definition like this — "This screen has one welcome line, and one button beneath it. Pressing the button calls the order tool." When the user opens the app, the device receives this definition and draws it as is. The line and the button appear.

Now you edit that definition on the server. "Make it two buttons, one to order, one to cancel. Color them blue." You save.

The next moment, the user's screen has two buttons. They did nothing. They did not tap update, did not redownload the app, did not go to the store. You did not build, did not wait for review, did not press a deploy button. You edited one line of the server's definition.

A ten-minute fix reaches every user in ten minutes.

That long chain from the opening — this is where it has vanished, all of it.

The objections that naturally arise

Any engineer who has read this far will have several objections in mind. If this piece does not answer them head-on, it stays an empty proclamation. Let us take them one by one.

"If the server defines the screen, then offline you can do nothing, no?" A fair worry. The answer — the screen definition is cached. A definition once received is stored on the device, and even with the connection lost the last screen still works. It asks the server only when a new definition is needed. The same principle by which the web made PWAs with offline caching, but on top of a native runtime. The misconception that "it must always be connected" comes from the false picture of calling the server every moment. In reality, traffic flows only when the definition changes.

"If every screen is fetched from the server, isn't it slow?" The screen definition is small. Not a heavy code bundle, but a light specification of "one button, one text." And as said above, it is cached. The heavy thing — the drawing engine — is already on the device, natively. The performance the user feels is native, plain and simple. What the server defines is what to draw, not the act of drawing itself.

"What about security? If the server sends down screens and behaviors, couldn't it send a malicious definition?" That is why the runtime does not trust the received definition but verifies it. The scope of what a definition can do is bound within boundaries the runtime sets — not arbitrary code execution, but only combinations of predefined widgets and tools. This is the same idea as a web browser running an arbitrary site's JavaScript only inside a sandbox. The server can say "draw this screen," but it cannot say "do whatever you like with everything on the device."

"Isn't this an app-store policy violation? Changing features without review." A subtle area, and honestly, it depends. Stores have been wary of "bypassing review to change an app's core behavior wholesale." But "the server defining content and screen composition" is what every feed, every commerce app already does. The line is at whether arbitrary native code is planted, not at whether the server defines the screen. As long as this model stays on the latter side, it is within policy, just as existing SDUI has been. (That said, this is an interpretation of platform policy, not legal or policy counsel. In real application you must check each store's latest guidelines.)

"What about server cost and dependency?" There is no free lunch. A server that sends down screen definitions must be running. But that burden — given that nearly every app already has a backend — is less something newly created than a role growing larger. And as we will cover later, in the ecosystem this magazine deals with, that server itself becomes the product.

Once these objections are answered, the "install-less app" is no longer magic but a structure explained by engineering. Magic deserves suspicion, but a structure can be verified.

What changes

When the premise changes, the things that stood on top of it change with it. It is not merely that "deployment gets easier."

When the cost of fixing approaches zero, the way of fixing changes. In a world where review takes three days and half the users are on the old version, you pack as much as you can into one release and send it out cautiously. Because if you make a mistake, undoing it takes another three days. But if a fix is reflected instantly and can be undone instantly, fixing small and often becomes natural. Change one screen today, and if the reaction is poor, undo it tomorrow. The unit of experiment shrinks. This is not mere convenience but a change in the very rhythm of making a product.

Who can make an app changes too. Setting up a build environment, managing signing keys, operating a store account, learning the review rules — all these barriers were attached to the act of "making an app." In a world where the screen is drawn from a server definition, much of that barrier disappears. If you can write a definition, a screen appears. What this means is large. Even someone who is not a development expert — someone who knows their own domain well — can make their own tool. A lawyer their own consultation flow, a farmer their own cultivation records, a factory engineer their own equipment-control screen. This is precisely the story this magazine will keep showing from here on.

And the meaning of the word "app" blurs. Not a heavy lump installed on the device, but a living screen defined by the server and drawn by the runtime. If so, then anything on the server side that can define tools and data and screens — is already an app. At the end of this thought lies a proposition this magazine will return to again and again. What if every server can become an app? Its implications are too large to fit in this single piece. The coming series will unravel them one by one.

So, doubt it

If you have read this far and think "but will that really work" — that doubt is right. A written vision can be made as plausible as you like. You can string history together convincingly and answer objections convincingly. What matters is whether it actually works.

So this magazine does not stop at laying out a vision at length. In the articles to come, we will build it and show it. Starting from putting up a single screen with no install, then handling state, calling the server's tools, and finally the process by which a factory's equipment, a hospital's care flow, and one person's expert knowledge become an app. One step at a time, with code, as something that actually runs.

Every claim this piece has thrown out — that the chain was never inevitable, that capability and chain can be separated, that anyone can make their own tool — is a promise to be repaid as evidence in the series to come.

One last thing to leave you with. When did you last tap "update app" on your phone? That familiar act — is beginning to disappear.


makemind.dev "Horizon" — This piece opens the volume "The Age of Install-less Apps." It carries on into "Your First Screen in Ten Lines": the shortest path to a screen with no build and no install.

Twitter