LemonadeHost help Main site Pricing Status

For developers

Publish a site you built with Astro, Vite, Hugo or Eleventy

We serve files. We never run a build — there is no build image, no install step and no command of yours that ever executes on our side. So the build runs where it already runs, on your machine or in your CI, and what you publish is the folder it wrote.

That is the entire difference between this and a host with a build pipeline, and everything below follows from it.

Which folder

Your build already writes one. These are the defaults:

ToolOutput folder
Astrodist
Vitedist
Hugopublic
Eleventy_site
Jekyll_site
Next.js, static exportout
Create React Appbuild

If yours is not here, it is whatever your own config says — the folder with index.html at its top level is the one.

Build for the root of a domain, not for a subfolder. Your site is served at the root of its own address, so a base path of / is what you want. A site built for /my-repo/ — which is what GitHub Pages often needs — will load its home page here and then fail to find its own stylesheets.

Route one: the command line

npx lemonade-host@latest deploy ./dist

That zips the folder, sends it, and prints the address. The package is lemonade-host, not lemonade — the bare name on npm belongs to somebody else.

Given no folder at all, the CLI looks for dist, build, out, public and _site, in that order, and takes the first one that exists and contains index.html. Failing all five it publishes the current directory, which is rarely what you meant, so name the folder in anything scripted.

You need a deploy token: portal → your site → Deploy tools. It reaches that one site, can publish and read its deploy history, and nothing else. See deploy tokens and the CLI reference for every flag.

--include-hidden publishes secrets. It is documented as a way to include dotfiles and node_modules, and it does that — but the same switch also lifts the guard on .env, .env.local, .npmrc, .netrc and SSH private keys. Reach for it knowing that.

By default every dotfile, every dot-directory, node_modules, .git and the usual build detritus are skipped, so a stray .env in your output folder is not published by accident. Symlinks are skipped always, and are never followed.

Route two: GitHub, with the publish folder

Connect the repository once and every push to the branch you chose republishes. Your site → GitHub → install the app on that one repository, then set:

The folder is a field you fill in. Nothing is detected: we take what is in the repository at that path and serve it. So this route works when the built output is committed. If your repository holds source that needs npm run build, either commit the build output to a folder and name it here, or build in CI and publish with the CLI instead.

Publish from GitHub has the rest, including what happens when a push does not publish.

Route three: build in CI, publish with the CLI

The common shape, and the one to use when you do not want built output in your history. Put the token in a repository secret called LEMONADE_TOKEN.

name: Publish
on:
  push:
    branches: [main]

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm ci
      - run: npm run build
      - run: npx lemonade-host@latest deploy ./dist --yes --json
        env:
          LEMONADE_TOKEN: ${{ secrets.LEMONADE_TOKEN }}

--yes because there is nobody to answer a prompt — though the CLI auto-confirms when its input is not a terminal, so it is belt and braces. --json so a failed step leaves your logs something parseable. The command exits non-zero when a publish is refused, which fails the job.

For Hugo or Eleventy, swap the build step and the folder: ./public and ./_site respectively.

What a publish does

Each publish replaces the whole site. It is not a sync — files you do not send stop being served. That is deliberate, and it is the only behaviour where deleting a page works the way you expect.

The limits, all of them checked before anything changes:

The zip256 MB
Any single file25 MB
Number of files20,000
The whole site, unpacked1 GB

A refused publish changes nothing — the release that was live keeps serving. Every refusal and its fix. The previous release stays restorable for seven days: going back to an earlier version.

What does not come with it

No server-side code of any kind, no request-time environment variables, no rewrites or redirect rules read from your files. If your framework has a server mode, build it in its static mode. Your CI secrets stay in your CI — nothing we hold is ever read at request time, because nothing of yours runs at request time.

Dynamic behaviour that a static site normally cannot have is available as apps, one of which is a working contact form.

Not sure which route suits you? The decision table is shorter than this page. Coming from another host? Moving your site here.

A site is 99¢ a month billed yearly, or $2.99 billed monthly, and a staging copy is a second site at the same price — the full price list.

Last checked against the product on 2026-09-23. Something wrong or missing? Tell us.