Home / Guides / Deploy with the htmldrop CLI
Dragging a file into the browser is the fastest way to get a single page live. For a real project — an Astro blog, a Vite app, a Hugo or Eleventy site with a build step — the faster path is the terminal. Install the CLI once, log in, and every deploy after that is one command: htmldrop deploy.
The recommended path is npm, whether or not you plan to keep Node around:
npm install -g @htmldrop.app/cli # or run it once without installing: npx @htmldrop.app/cli deploy
This installs a small JS launcher plus the correct platform binary for your machine as an optional dependency — there's no postinstall network fetch, so it works fine behind npm-registry-only firewalls. The npm package name is scoped (@htmldrop.app/cli), but the command it installs is plain htmldrop — you'll type htmldrop deploy, not the package name, and npx calls need the full @htmldrop.app/cli form shown above rather than the bare name.
If you'd rather not touch npm, grab a prebuilt archive for your platform from the GitHub Releases page — macOS, Linux, and Windows, arm64 and amd64 — verify it against the attached checksums.txt, extract, and put htmldrop on your PATH. Same binary either way; npm is just a convenient installer and updater on top of it.
Run:
htmldrop login
That opens your browser for a standard OAuth sign-in — approve it once and the CLI stores a token locally. If you don't have an account yet, the sign-in page creates one for free.
CI and other headless environments can't pop a browser, so create an API token from dashboard → API tokens and log in with it directly:
htmldrop login --token hsk_live_…
A token supplied this way never expires from the CLI's point of view and never triggers a browser — set it from your CI provider's secret store and every subsequent command in that job runs as your account.
cd into a project and run:
htmldrop deploy
On the first run in a directory with no htmldrop.jsonc, the CLI looks at what's there and figures out how to build it — Astro, Vite (including Svelte), Hugo, Eleventy, Jekyll, and Next.js with static export are all detected from their own config files, with a plain static folder or an npm project with a build script as fallbacks. It then asks for a site name and a slug (skip the prompts with --yes to accept the defaults and get a random slug), creates the site, runs the detected build command, and uploads the output. The result — including the detected build command and output directory — is written to htmldrop.jsonc in the project root, so every deploy after the first is non-interactive:
// htmldrop project configuration
{
"name": "my-astro-blog",
"site": "st_01h...",
"build": {
"command": "npm run build",
"output": "dist"
}
}
Commit that file if you like — it has no secrets in it, only the site ID and build config, so teammates and CI can deploy the same project without re-detecting anything. If you'd rather set the project up without deploying yet, htmldrop init runs the same detect-and-configure step on its own.
A couple of flags cover the edge cases: --dir <path> deploys a directory directly and skips the build step entirely (useful if you build in a separate CI step, or your framework isn't in the auto-detected list), --no-build skips just the configured build command and deploys whatever's already in the output directory, and --site <id-or-slug> overrides the project config to target a different site for one deploy.
Every deploy after the first only uploads what changed. The CLI diffs the files it's about to send against the version currently live, keeps the unchanged ones by reference, and uploads the rest — for a small content edit on a large site, that can be a handful of files instead of the whole build. There's nothing to turn on; it's the default behavior of htmldrop deploy once a site has a first version to diff against.
Delta uploads are available from the Starter plan up. On a free account, the CLI still works exactly the same way from your side — it just uploads the complete build every time and prints a note (delta not available on your plan — uploading everything) rather than failing. Pass --full on any plan if you want to force a complete upload anyway, for example after moving or renaming a lot of files.
See what's been deployed to the current site:
htmldrop deployments
And revert to an earlier one:
htmldrop rollback # back to the previous version htmldrop rollback 12 # back to a specific version number
Both commands resolve the site the same way deploy does — the current directory's htmldrop.jsonc, or --site <id-or-slug> to target another one. Rollback asks for confirmation before it acts; add --yes to skip the prompt in a script.
List everything on your account, or clean up ones you're done with:
htmldrop sites list htmldrop sites delete old-demo-site
These aren't scoped to the current project — they operate on your whole account, which makes them the quickest way to check what's actually live or to delete something you created ad hoc with htmldrop init and never followed through on.
Install the CLI, log in once, and every deploy after that is htmldrop deploy.
Astro, Vite (including Svelte), Hugo, Eleventy, Jekyll, and Next.js with static export are auto-detected from the files in your project — no config to write by hand. Plain static folders and npm projects with a build script work too. Anything else, point --dir at a build output folder or hand-edit htmldrop.jsonc.
Create an API token in dashboard settings, then run htmldrop login --token hsk_live_… (or set it however your CI injects secrets) instead of the interactive browser login. The token behaves the same as an interactive session for deploy, deployments, rollback, and sites commands.
Nothing to configure — after your first deploy, htmldrop deploy automatically uploads only the files that changed. It's available on Starter and up; free accounts upload the full build every time, and the CLI notes that and carries on rather than failing. Pass --full on any plan to force a complete upload.
Run htmldrop deployments to see the version history for the current site, then htmldrop rollback [version] to revert — omit the version and it rolls back to the previous one. You'll be asked to confirm unless you pass --yes.
Each project's htmldrop.jsonc pins it to one site, so htmldrop deploy always knows where to go. Use --site <id-or-slug> on deploy, deployments, or rollback to target a different site without changing the config, and htmldrop sites list / htmldrop sites delete <slug> to see and clean up everything on your account.