At some point in late 2025, I looked at what I was maintaining and realized the situation had gotten absurd. Four separate apps. Four repos. Four deployment targets. Four sets of environment variables. Four CI pipelines. All built by one person. All needing updates simultaneously whenever I changed something fundamental like the auth flow or the design system.
MGT Studio was the frontend. ClawFactory was the content automation backend. Mission Control was the agent orchestrator. Suite was the ops dashboard. Each one had its own port, its own package.json, its own Vercel project. They talked to each other over HTTP like microservices built by a 50-person engineering org. Except the org was me.
I merged all four into a single unified platform. Here's how, and what almost went wrong.
The Decision
The trigger was a Tuesday night where I needed to update a shared type definition across all four apps. I changed it in Studio, then remembered Factory imports it differently, then realized Mission Control had a stale copy, then spent 40 minutes chasing type mismatches across repos. For one type. One field.
That was the moment I decided: these are not four products. They are four modules of one product. They should live in one codebase, share one type system, deploy as one unit, and stop pretending to be independent services when they have never once been deployed independently.
How the Merge Worked
The approach was straightforward in concept, painful in execution:
- Studio became the hub. The Next.js frontend was already the most mature codebase. It had the design system, the auth layer, the navigation, and the most pages. Everything else got absorbed into it as route groups.
- Factory moved to /factory. All the content automation UI — templates, scheduling, analytics — became a route group inside Studio. Same components, same data fetching patterns, just nested under a different path.
- Mission Control moved to /control. The agent orchestration dashboard — agent status, task queues, execution logs — slotted into another route group. The real-time WebSocket connections needed refactoring to work with Studio's layout, but the core logic stayed intact.
- Suite moved to /ops. The operational dashboard — deployments, health checks, system metrics — became the /ops route group. This was the cleanest migration because Suite was already the simplest of the four apps.
Feature Flags
Not every deployment needs every module. A client project doesn't need the agent orchestrator. A personal deployment doesn't need the ops dashboard. So every module is gated behind the ENABLED_MODULES environment variable.
Set ENABLED_MODULES=factory,control,ops and you get everything. Set ENABLED_MODULES=factory and you get Studio plus Factory, nothing else. The nav adapts, the routes are excluded from the build, and the bundle stays lean. One codebase, configurable surface area.
The Backend Architecture
The frontend merged cleanly. The backends were harder. Four Python/Node services that each owned their own domain:
- Port 8000: Studio API — auth, user management, core data
- Port 8001: Factory API — content generation, scheduling, template engine
- Port 8002: Mission Control API — agent lifecycle, task queue, execution engine
- Port 8003: Suite API — deployment triggers, health polling, metric aggregation
I kept the backends as separate services but unified everything else. Shared secrets across all four. Identical webhook schemas so any service can emit events that any other service can consume. Environment variables documented in a single ecosystem map so I never have to wonder which service needs which key.
What Was Hard
Routing conflicts. When you merge four apps that each had their own /settings page, their own /dashboard page, and their own API routes, you get collisions everywhere. I spent an entire day just renaming and namespacing routes so nothing stomped on anything else. The route group pattern in Next.js App Router saved me — (factory)/settings, (control)/settings, (ops)/settings all coexist without conflict.
Shared auth state. Each app had slightly different assumptions about the auth context. Studio expected a full user object. Factory expected a user ID plus an API key. Mission Control expected a service token for agent-to-agent calls. Unifying the auth layer meant building a single session provider that could surface the right context depending on which module was active.
Independent deployability during the merge. I couldn't take all four apps offline for a week while I merged them. Each one was serving real traffic. So the merge happened incrementally — Factory first, then Mission Control, then Suite — with both the old standalone app and the new merged module running in parallel until I was confident the merged version was stable. Then I cut over and decommed the standalone.
26 routes compiling clean. By the time everything was merged, the app had 26 routes across all four modules. Getting them all to build without type errors, without missing imports, without circular dependencies, and without hydration mismatches took a full day of cleanup. The TypeScript compiler was not gentle about it.
Ecosystem Scripts
Managing four backends plus a frontend from the terminal is tedious. So I wrote ecosystem start and stop scripts:
- Start script: Boots all four backend services in sequence, waits for each health check endpoint to respond 200, then starts the Next.js dev server. If any service fails its health check, the script logs which one and exits before starting the frontend.
- Stop script: Gracefully shuts down all services in reverse order. No orphaned processes, no port conflicts on restart.
- Health checks: Each backend exposes a /health endpoint. The scripts poll these on startup and can be run independently to diagnose which service is down without opening four terminal tabs.
The Result
One app. 26 routes. Feature-flagged modules. One deployment target. One repo. One CI pipeline. One set of environment variables. One place to look when something breaks.
The entire merge — all four apps unified, all routes compiling, all backends synced, ecosystem scripts working — got done in a single session with 20+ parallel Claude Code agents. That is not an exaggeration. I deployed agents for routing, auth, type unification, build verification, script generation, and documentation simultaneously. The merge that would have taken a team a sprint took a solo dev a day.
Why This Matters
If you are a solo developer maintaining multiple apps that share users, share auth, share design systems, or share business logic — you probably should not be maintaining multiple apps. Every additional deployment target is operational overhead that compounds. Four apps means four places to rotate secrets, four CI configs to maintain, four Vercel projects to monitor, four sets of logs to check when something goes wrong at 2am.
The monorepo-vs-polyrepo debate gets a lot of airtime in engineering circles, but for solo devs the answer is almost always: merge it. You are not Google. You do not have a platform team to maintain the build tooling for 500 microservices. You have yourself, a terminal, and 24 hours in a day. Reduce the surface area. Ship one thing instead of four.
The unified MGT Studio platform is live and serving all modules from a single deployment. If you want to see how the feature flag system works or how the route groups are structured, the architecture is documented in the build log. And if you are thinking about a similar merge for your own projects, reach out — I have opinions.