GenerateSaaS

Eject

Permanently sever every GenerateSaaS tie - the heartbeat cron, the manifest, the internal license route, and the update tooling - leaving your application code untouched.

generatesaas eject is the permanent, supported opt-out from the license heartbeat. It deletes the CLI's connective tissue so the project becomes fully standalone; your application code and @repo/config flags keep working unchanged.

This is irreversible and requires typing eject to confirm. Commit first so the diff is reviewable, and note that you lose generatesaas update for good.

What it removes

Run it from the project root; it aborts if .generatesaas/manifest.json is missing.

TargetAction
packages/api/src/functions/maintenance/license-heartbeat.tsDeleted - the daily heartbeat cron
packages/api/src/lib/cron-spread.tsDeleted - the heartbeat's cron spreader
packages/api/src/lib/manifest.tsDeleted - the build-time manifest reader
packages/api/src/routes/internal/license.tsDeleted - the internal /license route
packages/api/tests/functions/license-heartbeat.test.tsDeleted - the heartbeat's own suite
packages/api/tests/lib/cron-spread.test.tsDeleted - the cron spreader's own suite
.generatesaas/Deleted - manifest dir (license token, version)
Bundled skill dirsDeleted - the shipped generatesaas-update and generatesaas-translate skills in every AI-tool root
packages/api/src/routes/inngest.tsModified - strips the heartbeat import + registration
packages/api/src/routes/internal/index.tsModified - strips the license route import + .route()
packages/api/src/routes/public/v1/health.tsModified - drops the manifest version from the health response
.gitignoreModified - removes .generatesaas entries

Shipped skill dirs are removed from every AI-tool root (.claude, .cursor, .agents, .gemini, .windsurf); skills you authored yourself in those roots are kept. Each delete is no-op-safe: missing targets are skipped, not errored.

How it runs

Reads .generatesaas/manifest.json; cancels with a non-zero exit if absent or unparseable.
Prompts you to type eject exactly; anything else (or Ctrl+C) cancels.
Sends one final, disclosed opt-out event to generatesaas.com (the heartbeat endpoint, marked event: "eject"), so a legitimately ejected project stays distinguishable from an unlicensed copy. Best-effort - ejecting works offline, and nothing is ever sent again.
Deletes the shipped skill dirs, the six API files above, then .generatesaas/.
Strips the heartbeat, license-route, and manifest references from the files above and cleans .gitignore.
Prints a per-file summary of everything deleted and modified.

If a file cannot be auto-modified because its lines shifted, eject logs a warning naming it so you can remove the references by hand - it never fails silently.

What survives, what is lost

SurvivesLost
All product code, pages, componentsThe daily heartbeat cron
Every @repo/config flag and the features it gatesThe dormant license layer (/license route, manifest reader)
Database, billing, auth, every backend packagegeneratesaas update - no more CLI-delivered version diffs

Common questions

QuestionAnswer
Can I undo an eject?No. The deletions are real filesystem changes with no restore path. Recovery means git revert or git checkout of the commit, which is why you commit first.
Will my app break afterwards?No. The removed files are GenerateSaaS infrastructure, not application logic, and the manifest reader already goes dormant when the token is empty.
Do I have to eject to stop the heartbeat?Only if you want it gone permanently. The heartbeat validates your install and sends no application or user data - eject is the clean removal, not a workaround.

On this page