---
title: Upgrade Hollware
description: Move a project to a newer release of Hollware, its tools and its files, apply the migrations, and know how to go back.
section: guides
order: 10
---

# Upgrade Hollware

An upgrade moves the packages of Hollware to a new release: its code, the migrations of its database and the admin. Your content stays where it is, in the database, and the migrations only add to it.

Every package of Hollware takes the same version, and moves together: `hollware`, `@hollware/core`, `@hollware/server` and `@hollware/admin` in the project, and `@hollware/client`, `@hollware/nuxt`, `@hollware/astro`, `@hollware/react` or `@hollware/vue` in your sites.

## Choose the release

The [release notes](https://github.com/hollware/hollware/releases) say what each release adds, and what it asks of your project, if anything. Within 1.x nothing of [what is promised](/docs/versions/) breaks: an upgrade is the packages, then a deploy.

```sh
npm view hollware dist-tags   # latest, and rc when a release candidate is out
```

pnpm, from version 11, installs nothing published less than a day ago: wait a day after a release, or name the version in `minimumReleaseAgeExclude` until then.

## Upgrade, step by step

### 1. The packages, exactly

```sh
npm install -E hollware@1.2.0 @hollware/core@1.2.0 @hollware/server@1.2.0 @hollware/admin@1.2.0
```

With pnpm, `pnpm add -E` with the same names. `-E` keeps the exact version, as `npm create hollware` wrote it: a project moves when you move it.

### 2. Compare with a project of the new release

Each release's starter pins the tools it was tested with, wrangler, the Cloudflare plugins, Vite+ and Vitest, and sometimes changes a file that is yours. To see both, make a project of the new release next to yours, without installing anything, and compare:

```sh
npm create hollware@1.2.0 ../my-cms-1.2.0 -- --no-install --no-git --name my-cms --site my-site
diff -ru --exclude node_modules --exclude .wrangler ../my-cms-1.2.0 .
```

Take what the new release adds:

- **`package.json`:** the versions of the tools in `devDependencies`, and any new script.
- **`wrangler.jsonc`:** new bindings and flags, and the `compatibility_date`. Keep yours where they differ on purpose: the ids it holds, your `HOLLWARE_PUBLIC_URL`, your routes and your names.
- **`vite.config.ts`, `vitest.config.ts`, `test/`:** as the new release has them, unless you changed them yourself.

Then install, refresh the types of the bindings and delete the comparison project:

```sh
npm install
npm run types
rm -r ../my-cms-1.2.0
```

### 3. Locally

```sh
npx hollware migrate --local
npm test
npx hollware doctor
```

`migrate` applies the migrations the local database lacks, and `doctor` says what the project is missing, a binding the new release needs among them. Start it with `npx hollware dev` and try what you use.

### 4. Deploy

```sh
npx hollware migrate --check --remote   # what the new release adds; it exits 1 while something is pending
npx hollware deploy
npx hollware doctor --remote
```

`hollware deploy` applies the new migrations to the remote database first, while the Worker you have still serves (migrations only add, so it keeps working on them), then deploys the new Worker and creates what it needs on your account, such as a bucket. It takes a D1 Time Travel bookmark before migrating, and prints it: keep it until you are sure.

Commit the project afterwards: `package.json`, the lockfile, `wrangler.jsonc` and `worker-configuration.d.ts`.

### 5. Your sites

Upgrade the Hollware first, and the sites that read it after, to the same version. Within 1.x a site on an older release keeps reading a newer Hollware, so nothing is urgent.

## Keep it up to date

A bot can open the upgrade for you, with every package in one pull request, never one at a time. With Renovate:

```json
{
  "packageRules": [{ "matchPackageNames": ["hollware", "@hollware/**"], "groupName": "Hollware" }]
}
```

With Dependabot, in `.github/dependabot.yml`:

```yaml
version: 2
updates:
  - package-ecosystem: npm
    directory: /
    schedule: { interval: weekly }
    groups:
      hollware:
        patterns: ['hollware', '@hollware/*']
```

The bot moves the packages; step 2, the comparison, is still yours when the release notes ask for it. Your CI runs `npm test`, and the deploy stays a command you run, or a job of your own.

## What each release asks of your project

### To 1.0, from 0.11

The packages, as above, and these files, which the comparison of step 2 shows. `npx hollware doctor` names any binding the project lacks.

- **`wrangler.jsonc`** gains the [images](/docs/images/) of your sites: an R2 bucket and the Images binding. Name the bucket after your Worker; the next deploy creates it.

  ```jsonc
  "r2_buckets": [{ "binding": "MEDIA", "bucket_name": "my-cms-media" }],
  "images": { "binding": "IMAGES" },
  ```

- **`vite.config.ts`** serves the local server at `http://localhost:5199` whatever `HOLLWARE_PUBLIC_URL` the deploy wrote, so `hollware dev` keeps working after a deploy, and gives it a `HOLLWARE_SECRET` for development, so preview links work locally. It also gains the `fmt` and `lint` settings of `npm run check`.
- **`vitest.config.ts`** gives the tests the same local URL, as the binding `HOLLWARE_PUBLIC_URL`.
- **`test/worker.workerd.test.ts`**: the test of the database checks that every migration is applied, instead of a list of tables that a new migration breaks. Take it as it is: the old one fails on the table of images.
- **`package.json`** gains the script `check`.

After the deploy, the cron rebuilds the stored documents of your revisions with the pipeline of the new release, twenty a minute; nothing is asked of you.

### From 0.x

A project of 0.x upgrades the same way, and takes what changed on the way to 1.0:

- **The structure of your sites lives in the database** (0.8). A `hollware.config.ts` is read once, on the first request of the new Worker, and moved into D1; after that, change your sites in the admin or over MCP, and delete the file.
- **Tokens** may have no expiry when you create them without `--expires-in-days` (0.11).
- **Every change is in the activity log** of its site (0.11); an owner decides, under **Site**, whether it keeps a hash of each address and for how long.
- **Previews of drafts** need the site's `url` and the Worker secret `HOLLWARE_SECRET`, which `hollware deploy` sets (0.11).
- **Invitation links** carry their secret after `#` (0.11); links made before still work.

## Going back

A deploy that went wrong goes back in two steps:

1. Install the previous versions again (`git checkout` of `package.json` and the lockfile, then `npm install`) and run `npx hollware deploy`.
2. If a migration of the new release changed data you need back, restore the database to the bookmark the deploy printed: `npx wrangler d1 time-travel restore <database> --bookmark <id>`. Everything written after it is lost. See [Restore](/docs/deploy/#restore).

Migrations only move forward, and none is ever undone. An older release runs on a database a newer one migrated when the new migrations only added, as nearly all do; the release notes say when one does more.
