One app per deliverable
Giant Context gives a business what it needs to reach its own customers, a website, email, a record of every customer, a form to capture the next one. Each of those is a deliverable, a distinct piece the product hands over. The platform is built as a separate application for each, rather than all of them living together in one program. Each already exists as its own app, with others beside them. The structure was decided for all of them at once, the largest architectural decision in the whole codebase.
It was made for two reasons. A platform split this way stays manageable by one person while it keeps scaling. A single program stops doing both at about the size this one is heading for.
The shape it did not take
The tempting shape is the monolith, one program that does everything. At the start it wins on every count that matters. There is one program to run, one place to look, and any part within reach of any other the instant it is wanted. The email code that needs a customer's address reaches over and takes it. Nothing is faster to build.
It stays best right up until the product has a few jobs and a few thousand files, and then turns. The convenience that made it fast to build is what makes it slow to change, because the parts come to depend on each other in every direction at once. Email holds a piece of the CRM, the CRM a piece of the website, the form a piece of email. Within months every part of the program depends on every other part. There are no components left, only one object with a thousand internal connections, most of them undocumented and every one of them load-bearing.
You feel it the first time a small change turns out not to be small. Someone renames one field on a customer, a five-minute edit. A report on the far side of the product goes blank, because a year earlier that report had been wired to read the field directly and no one wrote the connection down. The afternoon goes to hunting for a link nobody knew was there. The next week it happens again somewhere else. In a monolith there is no such thing as a local change. There is no local. Every edit is an edit to the whole, with no smaller unit to work in.
Manageability, the reason a solo builder feels first
You can only safely change a system you can hold in your head. No one holds a monolith in their head past a certain size. In a monolith every change is a change to the whole, because it is all connected. Each one risks breaking something far away for a reason you could not have seen coming. Past that size the honest state of the product is that its one maintainer is afraid to touch it.
Separate apps keep the unit you have to carry small. To change how one app works, I open that app and reason about that app alone. Nothing outside it depends on its insides, because nothing outside it is allowed to. Change them and nothing else breaks. Today that means I can rework the entire website builder and know, without checking, that there is nothing else it could have reached into or been reached from. The most I have to reason about at any moment is a single app, never the platform. That is the difference between a product a person can keep working on and one that has quietly grown past them.
Scalability, the reason it keeps earning
The second reason is what happens as the product grows. A platform earns by delivering more, more a customer can use and pay for and stay for. In a monolith, every time the product grows the program gets harder to change, because each addition is one more set of connections into everything else. The product gets larger and more fragile on the same day, until each addition costs more than it is worth.
Separate apps break that link. A new capability is a new app, cheap and safe to add at the same time. It is cheap because the app inherits the foundation every app already builds on and writes only the part that is genuinely its own. It is safe because nothing that already exists depends on it, so it changes nothing that already works. The next app coming is socials, a place to connect the customer's own social accounts. It sits beside the others, stands on the same foundation, and touches nothing that came before it. A monolith's cost of change climbs with its size. A set of separate apps holds that cost flat, which is the only way the product keeps expanding with one person behind it. The tenth app is no harder to add than the second.
At the start
Fastest to build, everything in reach
A little more setup
A small change
Can reach anything, anywhere
Stays inside one app
What you hold in your head
The whole program
One app at a time
Cost of growth
Rises with size, more fragile each addition
Flat, a new app touches nothing old
How the apps stay apart
The rule is short and runs one direction. Beneath all the apps sits a shared foundation, the database access and design system and types every app builds on. Every app may depend on it. What no app may do is depend on another app beside it. Dependencies run one way, down onto the foundation, never sideways between apps.
In the code, the direction is plain in the layout of the repository. Each app is its own package, with a dependency list that names the foundation packages and nothing else. No app's list names another app, because the workspace never wires the apps to each other. Adding a neighbor would be a deliberate line any review would catch. Opening any app and reading its dependencies tells you in a second exactly what it stands on. It is always the foundation and never a peer.
The apps still have to cooperate, which is where the shape earns its keep. When a visitor fills out a form on the customer's site, the forms app captures the lead and hands it to the CRM, the app that stores every customer the business has. When the email app has a message to send, it asks the CRM for that customer's address, at the moment it needs it, rather than reaching into the CRM and reading how it stores one. The CRM can rebuild everything behind that address and email is unaffected, because the only thing it depended on was the answer, not the machinery behind it. Each app does its one job and meets the others only at a stated interface, never inside.
For now the rule is mine to keep, not something the code enforces. With a handful of apps and one person across all of them, my knowing it is enough. It will not stay enough. The plan is to make the build itself refuse a sideways dependency before the apps multiply past what a tired person can track. Drawing the line early, while there is almost nothing on either side of it, is what will make that enforcement cheap to add rather than a rewrite.
Why the shape is the business
A product that can grow while one person keeps it changeable can compete without a team, and can keep competing as it grows. And the shape is not a feature a rival copies over a weekend, because it is not visible from outside. A product that grew as one monolith cannot be separated after the fact without pulling the running product apart. The separation is only cheap before the monolith forms. A competitor who skipped it early has to buy the expensive version now, if they can afford it at all.
Find the seam
Underneath both reasons is a single decision, made once and early. Find the seam a system naturally comes apart along, and separate it there before the parts grow into each other. In Giant Context that seam falls between the things the product hands over, which is why each one a customer buys is its own app. Another system splits somewhere else without changing the move. The cut is almost free while there is nothing on either side of it. Once something is there, it becomes the most expensive change you can make.
Building something like this
I'm Jesse. I build platforms end to end, and I'm open to work. If this is the kind of engineering you need, get in touch.