Start Here
Working Without the CLI
Everything the wheels CLI does to a running app goes through surfaces the framework itself provides — which means every one of them is reachable without the CLI. This page is the map. Bookmark it if you installed manually or run CommandBox.
The equivalents table
Section titled “The equivalents table”| Task | With the wheels CLI | Without the wheels CLI | Available in |
|---|---|---|---|
| Reload the app after config/code changes | wheels reload | ?reload=true&password=<your-reload-password> appended to any app URL | Any environment with a non-empty reloadPassword (rate-limited; set it in .env). Restarting the app server also reloads. |
| Run migrations | wheels migrate latest | Browser: the migrator GUI at /wheels/migrator. Programmatic: application.wheels.migrator.migrateToLatest() or .migrateTo(version) | GUI: development only. Programmatic: any environment. set(autoMigrateDatabase=true) runs pending migrations at application start. |
| Check migration status | wheels migrate info | /wheels/migrator (shows applied/pending), or application.wheels.migrator.getCurrentMigrationVersion() | GUI: development only. Programmatic: any environment. |
| Write a migration | wheels g migration <name> | Create app/migrator/migrations/[timestamp]_[description].cfc by hand — it's a plain CFC with up()/down(); copy any existing one as a starting point. See Migrations. | n/a (files on disk) |
| Run app tests | wheels test | /wheels/app/tests in a browser; append ?format=json for machine-readable results (that's all the CLI does) | Development only |
| Seed data | wheels seed | application.wheels.seeder.runSeeds() — callable from anywhere server-side (an admin action, a deploy hook, one-off script) | Any environment |
| Inspect routes | wheels routes | /wheels/routes in a browser, or the debug bar's Tools panel | Development only |
| App/framework info | wheels info | /wheels/info, or the debug bar's Environment panel | Development only |
| Install a package | wheels packages add <name> | Download the package release and extract into vendor/<name>/, then reload — packages are auto-discovered from vendor/*/package.json at startup. See Packages. | n/a (files on disk) |
| Generate models/controllers/scaffolds | wheels g … | No runtime equivalent — generators just write files. Copy the patterns from The Basics or the snippets under app/snippets/. | n/a |
| Upgrade the framework | wheels upgrade apply | Swap vendor/wheels/ with the new release's core zip — full recipe at Upgrading Without the CLI | n/a (files on disk) |
| Create a new app | wheels new | Two zip downloads — Manual Installation | n/a |
Why the "development only" rows are locked
Section titled “Why the "development only" rows are locked”The browser surfaces under /wheels/* (migrator GUI, test runners, routes, info) are gated by a development-only allowlist — since 4.0.4 (#2903) they return 404 in every other environment, and set(enablePublicComponent=true) cannot open them outside development. That's deliberate: they expose schema and internals no production app should serve.
So the production-safe versions are the programmatic ones: application.wheels.migrator.migrateToLatest() and application.wheels.seeder.runSeeds() called from your own protected code path (a deploy hook, an authenticated admin action), plus the URL reload — which works in production precisely because it demands the reloadPassword you set in .env. Production Configuration and Security Hardening cover hardening both.