Our new customer portal is now live!
Guides

Publish your site from a zip file

Without GitHub, you can publish your site from a zip file, yourself or through your AI assistant. Put in it what a repository would hold.

6 min · Beginner

Updated

In this guide

Zip upload is available on Node.js services where the Deploy a website form lets you choose Upload a zip as the source. On other services, sites are published from GitHub, as in the guide on deploying your first Node.js application.

When you create the site, choose Upload a zip as its source. You upload new versions on the site's Deploys page. If your AI assistant is connected to NordicHost, it can do this for you.

What goes into the zip

The zip holds what a GitHub repository would: your app's source code and the files its build needs.

  • package.json in the top folder. If the app is in a subfolder, as in a monorepo, enter that folder as the site's subfolder, for example /apps/web.
  • A lockfile: package-lock.json, pnpm-lock.yaml, yarn.lock or bun.lock. Without one, every build installs the newest versions of the packages that day, and your site may not work as it does on your computer.
  • The .env file, if your app uses one. We read your site's environment variables from it, but don't keep the file with the code.
  • A site of plain files needs only an index.html in the top folder.

The zip may be at most 200 MB. If the whole zip is inside one folder, you don't need to remove it: we take it off ourselves.

What stays out

The build installs the packages and builds your app itself, so these aren't needed. We leave them out if the zip has them:

  • node_modules
  • .git
  • .next, Next.js's built app
  • __MACOSX, .DS_Store and Thumbs.db, the operating system's own files

Leave out other built folders too, such as dist and build, if the build makes them. The smaller the zip, the faster it uploads.

Leave other secrets out. We keep the version with all its files except the .env files. So don't zip other secrets, such as an .npmrc file with an access token, or private keys (.pem, .key). Move them out of the folder before you zip it.

How to make the zip

Run the command in the project folder. The zip appears next to the folder, without node_modules, .git and .next.

  • Windows, PowerShell: Get-ChildItem -Force | Where-Object Name -NotIn 'node_modules', '.git', '.next' | Compress-Archive -DestinationPath ..\site.zip -Force
  • Windows, faster for a large project (PowerShell): & "$env:SystemRoot\System32\tar.exe" -a -c -f ..\site.zip --exclude=node_modules --exclude=.git --exclude=.next *. Windows's own tar.exe is named by its full path, because the tar that comes with Git can't make zips.
  • Git Bash on Windows, which has no zip command: powershell.exe -NoProfile -Command "Get-ChildItem -Force | Where-Object Name -NotIn 'node_modules', '.git', '.next' | Compress-Archive -DestinationPath ..\site.zip -Force"
  • macOS and Linux: zip -r ../site.zip . -x 'node_modules/*' '*/node_modules/*' '.git/*' '.next/*'

You can also zip the folder with the mouse: on Windows, right-click it and choose Compress to ZIP file (Windows 11) or Send to > Compressed (zipped) folder (Windows 10); on macOS, Control-click it in Finder and choose Compress. Then node_modules goes in too, so the zip is bigger. A zip downloaded from Bolt, Lovable or v0 works as it is when it has a package.json.

With your AI assistant

Once you have connected an AI assistant, such as Claude or ChatGPT, to your NordicHost account, and it can run commands on your computer, ask it to publish your project from a zip. It zips the project, uploads it, tells you what the check found and asks you before publishing. If it can't run commands, it gives you a link where you upload the zip yourself.

NordicHost adds the variables in your .env file to your site, not the assistant: it only learns the variables' names, never their values. Variables that steer the build or Node.js (such as NODE_OPTIONS) aren't added from a zip an assistant published: you add those yourself by uploading your .env file on the site's Environment page.

.env files

We take every file whose name starts with .env out of the code, and read your site's environment variables from them:

  • We read .env, .env.production, .env.local and .env.production.local, in that order. If a variable is in more than one, the later file's value stays.
  • A variable your site doesn't have yet is added to your site when you publish the version.
  • If your site already has the variable with a different value, your site's value is kept. You see these variables after the check, and can take the file's values with one click.
  • We don't read .env.development or .env.test: they are for development and tests.
  • From example files such as .env.example we read no values. We list the variables in them your site doesn't have, as a reminder.

The .env file itself isn't kept. You change variables on the site's Environment page, where you can also upload a .env file.

If a variable isn't added when a version is published, you get an email about it, and the Environment page shows the missing variables and why until they're added.

The check before the build

We check the zip before anything is built. You see what we detected: the framework or start command, the Node.js version, the package manager and the lockfile. If the zip can't be published, we tell you why, for example a missing package.json or start script, and what you can do.

Versions and rollback

Every zip you upload is a version of its own. You see the versions on the site's Deploys page: the file's name, size, time and who uploaded it. We keep the three latest versions and the live one, so you can go back to them. Older versions can no longer be restored.

Your service can upload at most 20 zips a day and 4 GB a month.