GenerateSaaS

Eject

Permanently sever every GenerateSaaS tie - heartbeat, manifest, license route, and update tooling.

generatesaas eject (packages/cli/src/commands/eject.ts) 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 you lose generatesaas update for good.

Before removing anything, eject sends one final, disclosed opt-out event to generatesaas.com (the same endpoint as the daily heartbeat, marked event: "eject"). It exists so a legitimately ejected project is distinguishable from an unlicensed copy. It is best-effort - ejecting works offline too - and nothing is ever sent again afterwards.

What it removes

Run 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/manifest.tsDeleted - the build-time manifest reader
packages/api/src/routes/internal/license.tsDeleted - the internal /license route
.generatesaas/Deleted - manifest dir (license token, version)
generatesaas-update skill dirsDeleted - installed AI update skills
packages/api/src/routes/inngest.tsModified - strips heartbeat import + registration
packages/api/src/routes/internal/index.tsModified - strips license route import + .route()
.gitignoreModified - removes .generatesaas entries

Skill dirs are resolved from the manifest's aiTools; if none are recorded, all known roots are cleaned. 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.
Deletes skill dirs, the three API files, then the .generatesaas/ directory.
Strips heartbeat and license-route references from the two barrels and cleans .gitignore.
Prints a per-file summary of everything deleted and modified.

If a barrel can't be auto-modified (its lines shifted), eject logs a warning naming the file so you can remove the references manually - it never fails silently.

What survives, what's lost

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

Frequently asked questions

Can I undo an eject? No. The deletions are real filesystem changes with no restore path. Recovery means git revert / git checkout of the commit - which is why you commit before running it.

Will my app break after ejecting? No. The removed files are GenerateSaaS infrastructure, not application logic; the manifest reader already goes dormant when the token is empty, so nothing user-facing depends on it.

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, supported removal, not a workaround.

On this page