← All case studies Heroku → Vercel

Angular apps left Heroku the week the free dynos ended

A few Angular SSR apps moved from Heroku to Vercel in November 2022, the week free dynos ended. The published change wraps the Angular server build in one Vercel function. One build error cleared after Node was set to 14x. The post does not move a database.

Stephen Mitchell published this on 25 November 2022. He had a few Angular projects on Heroku. He wanted a host that was still free and still fast, and he picked Vercel. The page is a file list for an Angular server build. His blog does not have a follow-up.

The opening line says the free tier has already stopped. The quote under it says the stop starts on 28 November 2022. That quote matches Heroku’s 25 August 2022 changelog word for word. Free dynos, free Heroku Postgres, and free Heroku Data for Redis would go away. Existing free dynos would be scaled down, free databases deleted, and new free dynos or databases could not be provisioned.

Heroku’s 28 November changelog is more specific than that sentence. Free dynos were converted to Eco dynos and scaled to 0. Hobby-dev databases in personal and team accounts were queued for deletion. Enterprise hobby-dev databases were converted to Mini. Mitchell’s page is about the web apps. He does not describe moving Postgres or Redis, and he does not say whether any of his apps hit that conversion.

The Heroku → Vercel playbook covers config vars, workers, and a database. Mitchell’s page is the Angular SSR shell around a Git deploy.

What Heroku was running

The script he deletes is named start: heroku. It runs node dist/PROJECT_NAME/server/main. On Heroku, a Procfile is what starts that process and keeps it up. PROJECT_NAME is his placeholder for the Angular output folder.

Vercel does not keep a Node process running from a Procfile. His replacement is a build hook plus a function. In package.json he swaps that start script for "vercel-build": "npm run build:ssr". Vercel runs vercel-build during the deployment, so the server bundle has to exist before the function loads it.

The function that replaced the dyno

He adds api/index.js. It requires ../dist/PROJECT_NAME/server/main and exports server.app(). That is the built Angular server, handed to Vercel as the function.

The vercel.json is version 2, with public true and the name test-universal. The name is a sample. One rewrite sends every path, "/(.*)", to /api, so the function handles the routes the dyno used to serve. includeFiles is dist/PROJECT_NAME/browser/** on api/index.js. The browser bundle has to travel with the function, because the server render reads those files and a function bundle does not include them on its own.

Then the page prints five git commands. Remove the heroku remote, run git init, add https://github.com/GIT_NAME-git/REPO.git as origin, rename the branch to main, and push. The GitHub URL is a placeholder too. After the push, he imports the repo in the Vercel dashboard.

The one error he names

He says Vercel builds and deploys the project when the build is clean. He hit one error. Setting the Node version to 14x in the project settings fixed it. He does not paste the error text.

There is no downtime figure, and no bill, beyond the free tier that was about to disappear. There is also no list of config vars. If the Angular app read Heroku config at runtime, that copy is outside this page.

If your app is this shape, an Angular server build plus a rewrite onto one function, his file list is the whole migration he published. If the app also has Heroku Postgres, a worker, or a scheduler, this post does not cover them. Do that with the playbook before you delete the Heroku remote. And if the build fails on the first import, the only fix he records is the Node version.