Deploy

On this page

A Kilim site is a folder of static files. Publish it in one of two ways:

  • Upload dist/ yourself. kilim build writes a complete site to dist/, and any host that serves files can take that folder as it is, through its own upload page, CLI or CI action.
  • Run kilim deploy. It builds the site, checks it (like kilim check), compares the output with what the target has, and uploads only the difference, through an adapter set in kilim.config.ts.
kilim deploy --dry-run     # build, check and list the changes; nothing is sent
kilim deploy               # build, check and upload
kilim deploy --no-check    # upload even when the check finds errors

Choosing a way

WayStatusForCredentialsOld files_headers, _redirects
Upload dist/stableany static hostthe host's ownup to youwhere the host reads them
gitstableGitHub Pages and other hosts that publish a branchthe git remote's own (SSH key, token)the branch has only the buildGitHub Pages ignores them
cloudflarePagesexperimentalCloudflare PagesCLOUDFLARE_API_TOKENeach deployment is completeused
s3experimentalAmazon S3, Cloudflare R2, MinIOAWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEYdeleted (deleteRemoved: true)not uploaded
sftpexperimentala VPS or hosting with SSHSFTP_PRIVATE_KEY, SFTP_PRIVATE_KEY_PATH, SFTP_PASSWORD or ssh-agentkept (deleteRemoved: false)not uploaded
ftpexperimentalshared hosting with only FTPFTP_PASSWORDkept (deleteRemoved: false)not uploaded

Stable ways are fully supported. Experimental adapters work and are tested against local stand-ins of the service (fake API servers, a local OpenSSH and FTP server), but have not been tried with real accounts yet, and their options may change in a minor release. Try them with --dry-run first, and report what you find.

The adapters live in @kilim-dev/core/adapters. Their options are checked when the config loads, and an error names the option and its line, e.g. kilim.config.ts:7: "deploy.project": .... kilim doctor checks them without building or uploading anything, along with the environment variables the adapter needs (such as CLOUDFLARE_API_TOKEN) and, for git, that git runs and the remote exists; for sftp, that the server's key is known.

Credentials always come from environment variables, never from the config, so kilim.config.ts can be committed. On a host that reads neither _headers nor _redirects, redirects from aliases and redirects.txt still work through the redirect pages Kilim writes; set the security headers and CSP in the server or CDN instead.

Before you publish

GitHub Pages and Cloudflare Pages answer missing URLs with 404.html at the site root (an S3 website does when it is set as the error document). Kilim writes it from content/404.md, whatever trailingSlash says; the page is noindex and stays out of the sitemap, feeds and collection lists. kilim preview serves it the same way, so try a missing URL there before you deploy. To check the site on a phone first, run kilim preview --host and open the "On your network" address it prints.

Set url in the config to the address the site is published at, so canonical links, the sitemap and feeds point there.

How a deploy works

  1. Build and check. kilim deploy builds the site and runs the same check as kilim check. Errors stop the deploy; --max-warnings <n> stops it on more than n warnings too, and --no-check skips the check.
  2. Plan. The adapter compares the build with what the target has and prints the files it adds, changes and removes. --dry-run stops here, so nothing is sent.
  3. Upload. Stylesheets, images and other files go first, then the pages, then deletions, so a visitor never gets a page whose assets are missing.
  4. Manifest. The s3, sftp, ftp and cloudflarePages adapters write _kilim/deploy.json last: the site's files and their hashes. The next plan reads it instead of downloading the site, and a deploy that stops halfway is completed by the next one.

deleteRemoved decides what happens to files of earlier deploys that the build no longer has. Files the adapter keeps stay in the manifest, so turning on deleteRemoved later still deletes them, and only them. Without a manifest (the first deploy, or files put there another way), the adapter cannot tell its files from others: with deleteRemoved: true it deletes everything in the target that the build lacks, so look at kilim deploy --dry-run first.

In CI

Run kilim doctor before the deploy step: it checks Node.js, the config, the theme, url and the adapter's options and environment variables, without building or connecting. With --json it prints the checks for other tools, and --max-warnings 0 makes a warning fail the job:

kilim doctor --max-warnings 0
kilim deploy --max-warnings 0