Evaluate and merge template updates

Define the update's goal and compare the old template, new template, and your application to preserve customizations while adopting the changes you need.

Use this article as a reference when you have a specific reason to update. The template currently has no tool for automatically merging source changes into customized projects. Reading this article does not require you to update your existing project now.

1. Define why you need this update

Before you begin, write down what you want to resolve, which version or commit you plan to adopt, and which application behaviors must stay the same.

For example, “Apply a particular email delivery fix while preserving our registration rules and email copy” is easier to evaluate and validate than “Sync with the latest template.” A clear goal lets you decide which changes are necessary and which can wait.

InformationWhat to record
Current application stateBranch, commit ID, application version, and uncommitted changes
Original template sourceTemplate version, tag, commit, or source archive records from initialization
Target sourceThe specific tag, commit, or source archive with a verifiable version to use for this update
ScopeFeatures, dependencies, configuration, data, and external services
Acceptance criteriaHow you will confirm that the original problem is resolved and existing features still work

Record the template version and application version separately. Changing the application's package.json.version does not upgrade its source code or database. Updating the CLI does not change applications it has already generated either.

2. Preserve your current work

Once you have a specific upgrade plan, prepare a separate branch or copy for it. Inspect your current work first so that unfinished changes and template updates do not become one large change.

git status --short
git log -5 --oneline
git diff --stat

These commands only read the current state. Confirm that your existing changes are safely saved before creating a branch for evaluation and merging. A Git branch only preserves committed code. It does not back up D1, uploaded files, Secrets, or third-party platform settings.

Keep the original project directory. Do not extract a newer ZIP over it or treat another saavo create run as an in-place upgrade.

3. Compare three versions

Ideally, keep all three of the following:

VersionPurpose
The old template used at initializationEstablish your starting point
The new template you plan to adoptIdentify the actual upstream changes
Your current applicationIdentify your customizations and existing data constraints

First, compare the old template with the new template to understand the upstream changes. Then compare the old template with your application to understand your own changes. Finally, decide how to apply the upstream changes to your current application.

If your repository and the template do not share Git history, compare directories or apply patches change by change. Do not force unrelated histories together just to make a merge command work. A Git merge only has a sound basis once you have confirmed usable shared history and a trustworthy remote source.

If the old template's source is unknown, use the project's initial commit, download records, and file contents to narrow it down. Record anything you cannot confirm as uncertain. Do not assume that an arbitrary older version was your actual starting point.

Initialization itself creates differences

The CLI changes the project name, application version, and resource names for Workers, D1, R2, and Queues. Production deployment also writes account information, resource IDs, and production URLs. Published source archives also omit package-lock.json and the maintainer-only commit script.

These differences do not necessarily indicate omissions or errors. Preserve your project's identity and remote bindings when comparing versions. Do not replace resources already in use with the new template's placeholder configuration.

Location of changesWhat to check together
src/core/, src/api/Domain types, database access, business rules, DTOs, pages that call them, and tests
config/Schemas, code that reads configuration, business keys, and existing configuration values
schema/Migration paths for existing databases and initialization paths for new projects
package.jsonDependency constraints, scripts, and runtime requirements
wrangler.jsoncThe original project's resource identities, new bindings, and queue and scheduled entry points
example.varsEach variable's purpose, where it is read, and whether development and production both require it
locales/, content/New translation keys, navigation, language configuration, and your project's own content

When conflicts occur, understand the intended business behavior on both sides before merging. For example, a new upstream email verification check does not mean you should overwrite your existing registration policy. Preserving old code must not cause you to miss security fixes that the check depends on either.

For database access changes, preserve the responsibility boundaries in schema → core/db → core/repositories → service → API → UI. Do not let pages read database types directly or add ad hoc SQL to an API just to resolve conflicts quickly.

Track related changes when merging selectively. A fix may introduce a new field, migration, configuration option, and test together. Copying only the Handler can leave missing pieces that cause problems at runtime.

5. Handle dependency changes separately

Merge the required dependency declarations first, then use your project's package manager to generate a consistent lockfile. Do not combine lockfiles manually or expand the dependency changes into an update of every package to its latest version.

After evaluating dependency changes in package.json, you can run:

npm install

Review the generated lockfile diff to confirm that it does not include broad updates unrelated to your goal. For subsequent installations in a clean environment, you can use npm ci to install from the committed lockfile.

If upstream raises its Node.js requirements, update your development environment, build environment, and continuous integration settings as well. Check the project's engines, scripts, and dependency requirements instead of relying on a single outdated template document.

6. Verify local behavior first

After merging the necessary changes, run checks appropriate to what you changed. You can start with npm run doctor to inspect configuration. Regenerate types if bindings have changed. Only validate migrations when you have actually prepared database changes.

Once the code merge is complete, run:

npm run verify

This runs linting, type checking, tests, and a build. After these checks pass, reproduce the problem you intended to fix and validate related workflows. For example, after fixing payment callbacks, check duplicate deliveries and entitlement grants rather than just opening the home page.

If you encounter pre-existing failures unrelated to the merge, record them and distinguish their source. Do not silently weaken tests or remove validation to make the command pass.

7. Prepare the update for review

Before deployment, you should be able to explain which upstream changes you adopted, which application differences you preserved, whether data or configuration migrations are needed, what you tested, and how to recover from a failure.

If there are no data changes, continue to Validation and deployment. If the update affects table structures, configuration, resources, or persistent keys, read Migrate data and configuration first.