New to Rust? Grab our free Rust for Beginners eBook Get it free →
Migrating a Legacy Angular Heroku App: Static Hosting or SSR?

If you maintain an Angular application that still uses an Express server on Heroku, first decide whether the server only serves an Angular browser build or performs server-side rendering (SSR) or other request-time work.
That distinction determines the replacement. A client-rendered Angular build can move to Firebase Hosting as static files.
A new Angular SSR project should use Firebase App Hosting. For the complete client-rendered Firebase Hosting walkthrough, including the emulator and preview-channel checks, use How to Deploy an Angular App to Firebase Hosting.
Decide what the Heroku server actually does
Start with the current start command, server entry point, and Angular build output. If the server only returns index.html, JavaScript, CSS, and assets, it is acting as a static file server. If it renders Angular on a request, handles authenticated server routes, or owns API endpoints, removing it changes application behavior.
| What the Heroku app does | Migration decision | Why |
|---|---|---|
| Serves a browser-only Angular build and an index.html fallback | Use Firebase Hosting for the static browser build | Firebase Hosting serves static assets from the configured public directory and can return the Angular shell for client-side routes. |
| Runs Angular SSR for new requests | Use Firebase App Hosting for the new SSR project | The static Hosting configuration does not deploy a server-rendered Angular application. |
| Runs a separate API or worker | Keep or migrate that backend separately | Uploading Angular files does not move server routes, credentials, data access, or background work. |
This page does not replace a backend migration plan. It helps you avoid treating an Express wrapper around static files as proof that the application needs a server runtime.
Use Firebase Hosting only for the client-rendered branch
Choose this branch only when the Angular production build produces the browser files you intend to serve and the router owns the application routes. The checked Angular CLI 22.1.2 build wrote its browser output to dist/angular-firebase-demo/browser. Your directory can differ, so use the output reported by your own build.

The static Firebase Hosting configuration below is for a client-rendered Angular application only, and Firebase documents the public directory setting as the directory deployed to Hosting. Its rewrite behavior serves index.html for an unmatched route, so Angular Router can resolve a direct visit such as /settings, but this configuration does not deploy SSR.
{
"hosting": {
"public": "dist/angular-firebase-demo/browser",
"ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
"rewrites": [{"source": "**", "destination": "/index.html"}]
}
}
Run your production build before deployment, confirm that index.html is inside the configured directory, then test the Hosting configuration locally with the Firebase emulator and request a deep link. The linked Firebase Hosting tutorial contains the full initialization, emulator, preview, and deploy sequence rather than duplicating it here.
Move new Angular SSR work to App Hosting
Firebase’s current Angular Hosting documentation says that new participation in the Firebase Hosting frameworks experiment is closed permanently. It directs Angular developers already using that experiment to graduate to App Hosting. Do not newly enable or recommend that Hosting SSR route for a new project.
For a new Angular application that needs SSR, use Firebase App Hosting. Its framework-aware deployment path is the current Firebase recommendation for that decision. Existing framework-experiment users may encounter the legacy route, but that is a migration note, not an onboarding choice.
Separate the browser build from the backend before cutover
A static migration does not carry over an API just because the Angular application calls it. Keep the API URL in the production environment configuration, verify cross-origin resource sharing (CORS) on the API, and move secrets out of client code. The Angular HTTP client walkthrough covers the browser request layer.
- List every process declared by the Procfile or start command.
- Classify each process as static-file serving, Angular SSR, API work, or background work.
- For a browser-only application, build Angular and verify the browser output directory before configuring Firebase Hosting.
- For new SSR work, choose Firebase App Hosting instead of the closed Firebase Hosting frameworks experiment.
- Test the root page and a direct client-side route after the static deployment, then test API calls independently.
Account for Heroku plan retirement
Heroku announced the end of its free product plans on November 28, 2022. If your Angular application still depends on that Heroku process, classify its runtime work and choose the static-hosting, SSR, or backend path that matches it.
Migration questions
Can I move an existing Angular Heroku app to Firebase Hosting?
Yes, if the Heroku process only serves a client-rendered Angular browser build. Configure Firebase Hosting with the browser build directory and the index.html rewrite, then test a deep route. Move APIs and workers separately.
Should a new Angular SSR project use Firebase Hosting frameworks?
No. Firebase’s Angular Hosting documentation says new participation in the frameworks experiment is closed permanently. Use Firebase App Hosting for a new Angular SSR project. Existing framework-experiment users may see the legacy route and should plan an App Hosting migration.
Does firebase.json deploy an Angular SSR application?
No. The static firebase.json example on this page is only for a client-rendered Angular browser build. It does not deploy an Angular server runtime.




