To deploy a Next.js app from GitHub, you make sure it builds cleanly with npm run build, push it to a repository, connect that repository to a host that runs Node.js, set the install, build and start commands and your environment variables, then point your domain at it. After that, every push to your main branch deploys automatically. This guide walks through each step, with the commands and the mistakes that most often break a first deploy.
Step 1 - Check that your app builds locally
Most failed deploys are build failures that would also happen on your laptop. Run a clean production build first:
rm -rf node_modules .next
npm ci
npm run build
npm start
npm ci installs exactly what is in your lockfile, which is also what a good build server does. If it complains that package.json and package-lock.json are out of sync, run npm install once, commit the updated lockfile and try again.
Open http://localhost:3000 and click through the important pages. If it works here with npm start, it will work on a server.
Step 2 - Get package.json ready
Your package.json should have the standard scripts and a pinned Node.js version:
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start"
},
"engines": {
"node": ">=22"
}
}
next start listens on port 3000 by default, and uses the PORT environment variable if one is set, so you rarely need to hard-code a port. Next.js 16 requires Node.js 20.9 or later; Node.js 24 LTS is the safest choice today.
If you use pnpm or Yarn, commit its lockfile and set the packageManager field so the build server uses the same tool and version.
Step 3 - Keep secrets out of Git
Check your .gitignore includes these lines (create-next-app adds them for you):
.env*
.next/
node_modules/
Environment variables belong in your host's dashboard, not in the repository. Remember the rule from Next.js environment variables in production: anything prefixed NEXT_PUBLIC_ is baked into the browser bundle at build time, so it must be set before the build runs, and it must never contain a secret.
Step 4 - Push to GitHub
If the project is not on GitHub yet:
git init
git add .
git commit -m "Initial commit"
git branch -M main
git remote add origin https://github.com/your-org/your-app.git
git push -u origin main
Private repositories are fine; the host gets access through the GitHub connection, not a public URL.
Step 5 - Create the app and connect the repository
On NewHost, the flow in the dashboard at app.newhost.co.za looks like this:
- Create a new app.
- Connect your GitHub (or GitLab) account and pick the repository.
- Choose the branch that should deploy to production, usually
main. - Confirm the commands:
| Setting | Typical value |
|---|---|
| Install command | npm ci |
| Build command | npm run build |
| Start command | npm start |
- Add your environment variables (database URL, API keys,
NEXT_PUBLIC_values). They are stored encrypted. - Deploy.
From then on a webhook triggers a new deploy every time you push to that branch. There is nothing to SSH into and no process manager to configure.
If you use output: 'standalone' instead, the build command stays the same but the start command changes to running server.js from the standalone folder, after copying the static assets in. Next.js standalone output explained covers the exact commands.
Step 6 - Add a custom domain
Once the app is live on its default address, add your own domain:
- Add the domain (for example
www.yourbusiness.co.za) to the app in the dashboard. - Create the DNS records the dashboard shows you. If the domain already uses NewHost DNS, you manage those records in the same dashboard. If DNS is elsewhere, add them at your current DNS provider.
- Wait for DNS to propagate. With a low TTL this is often quick, but allow for longer.
Decide whether www or the bare domain is your main address, and redirect the other one to it, so search engines see one canonical site.
Step 7 - SSL
NewHost issues a free Let's Encrypt certificate for your domain and renews it automatically. The certificate can only be issued once DNS points at the app, so if HTTPS is not working yet, check your DNS records first.
After HTTPS works, confirm that http:// redirects to https:// and that the page loads without mixed-content warnings (images or scripts still loaded over http://).
Step 8 - Use preview deploys for other branches
On the Developer plan and up, pushing a branch other than production gives you a separate preview URL, so you can test a feature or show a client before merging. Up to 5 previews run per app; each is removed when the branch is deleted or after 14 days without a deploy.
Common first-deploy problems
| Symptom | Likely cause | Fix |
|---|---|---|
| "Module not found" on the server but not locally | Import path case differs from the file name (macOS and Windows ignore case, Linux does not) | Match the case exactly, e.g. ./Header vs ./header |
Build fails at npm ci |
Lockfile out of sync | Run npm install, commit the lockfile |
NEXT_PUBLIC_ value is undefined in the browser |
Variable added after the build | Set it, then redeploy so the build picks it up |
| Build succeeds, pages error at runtime | Missing server-side environment variable | Add it and restart or redeploy |
| Build runs out of memory | Large app on a small plan | Check for accidental huge imports, or move to a plan with more RAM |
Frequently asked questions
Do I need GitHub Actions to deploy Next.js from GitHub?
No. With a host that supports Git deploys, the host receives a webhook on each push and runs the build itself. You can still use GitHub Actions for tests and linting on pull requests, alongside the host's deploys.
Can I deploy from GitLab instead of GitHub?
Yes. NewHost supports both GitHub and GitLab repositories with the same push-to-deploy flow.
Why does my NEXT_PUBLIC variable still show the old value?
NEXT_PUBLIC_ variables are inlined into the JavaScript at build time. Changing the value in the dashboard does nothing until a new build runs, so trigger a fresh deploy after changing one.
How do I deploy a Next.js app in a monorepo?
Point the host at the repository and set the install, build and start commands to run in the app's folder, for example npm run build --workspace=apps/web. If you use standalone output in a monorepo, set outputFileTracingRoot to the repository root.
How long does a deploy take?
It depends mostly on your dependencies and the size of the app, because npm ci and next build do most of the work. Keeping dependencies lean and the lockfile committed keeps builds quick and predictable.
Want push-to-deploy on South African servers, billed in rand? Start with NewHost Next.js hosting or compare plans on the pricing page.