From the team behind aidrop.it — one workspace to build, host, and keep changing your code.
An agent scaffolds a project and you get api/ and web/ in one repository. That is a sensible layout. Then you try to deploy it and discover the assumption underneath most hosting: one repository, one running thing, one port — one more of the operational decisions AI does not make for you.
Those two directories are not one running thing. The API is a long-lived server; the frontend is static files or a small renderer. They fail differently, they scale differently, and they should be able to ship without each other.
The repository is a unit of source control. It is not a unit of deployment, and treating it as one is what forces the awkward workarounds.
The workarounds cost more than the split
The usual fixes are a process manager running both in one container, or a build that copies the frontend into the backend's static directory.
Both work, and both give you one thing that restarts when either half changes. A frontend typo now redeploys the API. A crash in one takes the port with it. Logs interleave, and "which one is broken?" becomes a question you answer by reading rather than by looking.
The cost is not theoretical: it lands the first time you want to roll back the frontend and find that the only artefact you have contains both.
One deployable, one address, one lifecycle
Split them into two deployments over the same repository. Each builds from its own directory, gets its own address, and redeploys on its own.
What they still share is the thing worth sharing: the code history, the decisions, and the rules a change has to follow. Two deployments do not have to mean two projects' worth of context — the same repository can back both, which is exactly the case that a one-repository-one-deployment rule makes impossible.
The frontend then calls the API over its public address, which is the same thing it will do in production anyway. Discovering that early is a feature; discovering it at cutover is a bad afternoon.
Where the line actually falls
Split when two parts have different lifecycles. Keep them together when they do not.
- Different runtime shape. A server that holds connections and a bundle of static files are not the same kind of thing.
- Different release rhythm. If one ships daily and the other monthly, one container makes the slow one hostage to the fast one — a separate question from how many environments each of them needs.
- Different failure blast radius. A worker that dies should not take the page with it.
- But not just because they are separate folders. A helper module used by one service is not a second service; splitting it buys you a network hop and a deploy to maintain.
The question is not how the code is organised. It is what has to be able to restart without the other.
The part that survives the split
Two deployments create a coordination problem that a monolith did not have: which version of the API does this frontend expect, and who knows that?
Write it down. A recorded decision — this endpoint shape, this contract, this is why the retry is where it is — is what stops the second service being changed on assumptions about the first. That is the same gap generated code opens when the reasoning is discarded, and it widens faster once there are two things to keep in step.
FAQ
Is a monorepo the wrong choice, then? No. A monorepo is a fine way to keep source together. The mistake is assuming the deployment must mirror it.
What about the extra cost of running two things? Real but usually small, and often less than the capacity you were over-provisioning to fit both in one box. On aidrop.it two deployments over one repository is a supported shape rather than a workaround: they are two Services, and they draw on the plan's shared memory and CPU rather than taking extra slots.
How do they talk to each other? Over the public address, with the same authentication a third party would use. Anything else works locally and surprises you later.
Should the split happen at the start? If you already know the two halves ship separately, yes — it is much cheaper before there is a build that assumes otherwise.
Do I need a separate database for each? Usually not. Shared data with one owning service is simpler than two databases and a sync problem.
Cover: https://unsplash.com/photos/7FzBaGN5XTM by Sergej on Unsplash. Alt text: Two parallel railway tracks running side by side through a green forest.
Get it running from the session you are already in
Connect your coding agent over MCP and ask it to deploy. aidrop builds the repository and runs it on a public address; when a build or the app fails, the log says why, and your agent fixes it and builds again.