Removing an App
How to safely deprecate and remove an app from the monorepo.
When to Remove an App
You should remove an app when:
- It has been replaced by another app (e.g.,
database-viewer→database-accessor) - It is no longer used and has been decommissioned
- Its features have been consolidated into another app
Removing an app is a multi-step process. Rushing it can leave orphaned services, broken references, or lost features. Follow the phases below in order.
Phase 1: Migrate Features
Before removing anything, make sure the replacement app has all the features from the app being removed.
Checklist
- Compare both apps' features side by side (pages, API routes, components, lib files)
- Port any missing features to the replacement app
- Update the replacement app's documentation (
README.md,CLAUDE.md,PLAN.md,ai_docs/) - Verify the replacement app builds successfully
- Create a PR for the migration and get it merged
Tips
- Check both apps'
_lib/directories for utility functions that might need porting - Compare
_components/directories for UI components - Look at API routes in
app/api/for any endpoints the replacement is missing - Review access control and auth patterns — they may differ between apps
Phase 2: Prepare Infrastructure
Before removing code, tear down the deployed services. This prevents orphaned deployments that continue running and billing.
Railway Teardown
- Open the Railway dashboard
- Find the app's service (both staging and production)
- Remove or delete the service from each environment
- Confirm the service is no longer running
App Portal
If the app is registered in the App Portal (app_portal_apps table):
- Set the app to inactive, or
- Remove the entry entirely
Database Tables
If the app owns database tables that are no longer needed:
- Remove the Prisma model from
shared/database/prisma/schema.prisma - Remove the documentation from
shared/schema.md - Do not delete existing migration files — Prisma needs them for history
- The CI pipeline will auto-generate a drop migration when it detects the schema diff
Important: If your PR includes schema changes that drop tables, wait for the CI bot to commit the generated migration file to your branch before merging. The merge-to-main workflow only runs
prisma migrate deploy— it does not generate migrations. Merging without the migration file will leave the production database out of sync withschema.prisma.
# After editing schema.prisma, check the diff
git diff shared/database/prisma/schema.prismaPhase 3: Remove Code
Now remove the app and all its references from the codebase. Here is the complete checklist:
App Directory
Delete the entire app directory:
rm -rf apps/old-app-nameGitHub Actions Workflows
Delete the deployment workflow files:
rm .github/workflows/deploy-app-old-app-name-staging.yml
rm .github/workflows/deploy-app-old-app-name-production.ymlRoot package.json Scripts
Remove the dev, build, and start scripts from the root package.json:
// Remove these lines:
"build:old-app-name": "pnpm --filter old-app-name build",
"start:old-app-name": "pnpm --filter old-app-name start",
"dev:old-app-name": "pnpm --filter old-app-name dev",Documentation References
Search the entire repo for references to the removed app and update them:
Common places to check:
| File | What to update |
|---|---|
VIBE_CODING_INSTRUCTOR_GUIDE.md | Remove or replace app section |
templates/web/README.md | Replace if used as example |
plans/ directory | Delete obsolete plan files |
Other apps' PLAN.md | Update references to the removed app |
Update Lockfile
After deleting the app, update the pnpm lockfile:
pnpm installPhase 4: Create PR and Verify
Build Check
Verify that the remaining apps still build:
# Build the replacement app
pnpm --filter new-app-name build
# Check no other app imported from the removed app
# (Claude can search for cross-app imports)Create the PR
Create a single PR with all the removal changes:
git checkout main && git pull origin main
git checkout -b feature/remove-old-app-name
# Stage all changes
git add -A
git commit -m "chore: remove deprecated old-app-name app"
git push -u origin feature/remove-old-app-name
# Create PR via GitHub CLI
gh pr create --title "chore: remove deprecated old-app-name" --body "..."PR Checklist
Before merging, verify:
- Railway services are already torn down (staging + production)
- App portal entry deactivated or removed
- App directory deleted
- Workflow files deleted
- Root package.json scripts removed
- Prisma schema models removed (if applicable)
- CI-generated drop migration committed to the branch (if schema changed)
-
shared/schema.mdupdated - Documentation references updated
-
pnpm installran to update lockfile - Replacement app still builds successfully
- No cross-app imports from the removed app
Real-World Example
The database-viewer app was removed from this monorepo after its features were consolidated into database-accessor.
What happened:
- Migration PR (#516) — Ported dynamic table categorization from
database-viewertodatabase-accessor, added stats counter UI, updated all documentation - Railway teardown — Removed both staging and production services from Railway dashboard
- Removal PR (#517) — Deleted 61 files (~6,800 lines): entire app directory, two workflow files, root scripts, obsolete plans, updated instructor guide and template references
- Result — Zero cross-app breakage,
database-accessorbuilds and runs with all features intact
Quiz
What should you do BEFORE removing the app's code from the repository?
Next Steps
- Learn about the Monorepo structure
- Review the Branching & PRs workflow for creating removal PRs