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-viewerdatabase-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

  1. Compare both apps' features side by side (pages, API routes, components, lib files)
  2. Port any missing features to the replacement app
  3. Update the replacement app's documentation (README.md, CLAUDE.md, PLAN.md, ai_docs/)
  4. Verify the replacement app builds successfully
  5. Create a PR for the migration and get it merged
Ask Claude to compare two apps
Claude prompt
Compare the features of apps/old-app and apps/new-app. List all features present in old-app that are missing from new-app, including pages, API routes, components, and library functions.

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

  1. Open the Railway dashboard
  2. Find the app's service (both staging and production)
  3. Remove or delete the service from each environment
  4. 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:

  1. Remove the Prisma model from shared/database/prisma/schema.prisma
  2. Remove the documentation from shared/schema.md
  3. Do not delete existing migration files — Prisma needs them for history
  4. 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 with schema.prisma.

Verify schema changebash
# After editing schema.prisma, check the diff
git diff shared/database/prisma/schema.prisma

Phase 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:

Delete the appbash
rm -rf apps/old-app-name

GitHub Actions Workflows

Delete the deployment workflow files:

Delete workflow filesbash
rm .github/workflows/deploy-app-old-app-name-staging.yml
rm .github/workflows/deploy-app-old-app-name-production.yml

Root package.json Scripts

Remove the dev, build, and start scripts from the root package.json:

Lines to remove from package.jsonjson
// 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:

Ask Claude to find all references
Claude prompt
Search the entire monorepo for all references to "old-app-name" (excluding apps/old-app-name/ itself). Check package.json, GitHub workflows, CODEOWNERS, VIBE_CODING_INSTRUCTOR_GUIDE.md, templates/, shared/schema.md, and any other files that reference this app.

Common places to check:

FileWhat to update
VIBE_CODING_INSTRUCTOR_GUIDE.mdRemove or replace app section
templates/web/README.mdReplace if used as example
plans/ directoryDelete obsolete plan files
Other apps' PLAN.mdUpdate references to the removed app

Update Lockfile

After deleting the app, update the pnpm lockfile:

Update lockfilebash
pnpm install

Phase 4: Create PR and Verify

Build Check

Verify that the remaining apps still build:

Verify buildsbash
# 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:

Create removal PRbash
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.md updated
  • Documentation references updated
  • pnpm install ran 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:

  1. Migration PR (#516) — Ported dynamic table categorization from database-viewer to database-accessor, added stats counter UI, updated all documentation
  2. Railway teardown — Removed both staging and production services from Railway dashboard
  3. 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
  4. Result — Zero cross-app breakage, database-accessor builds and runs with all features intact

Quiz

Quiz

What should you do BEFORE removing the app's code from the repository?

Next Steps