How Updates Work

Components are distributed one way: from this library's catalog into your project, over HTTP. There is no lockfile, no verify command, and no registry client. What makes updates manageable anyway is git, and specifically the commit the starter's installer writes for every install:

text
component: install hero@1.3.2 from nunjucks-components.com

Component-Name: hero
Component-Version: 1.3.2
Content-Hash: a3f9c2e17b40d8e6

That commit is the baseline. It records exactly which files arrived, and everything you changed afterward is onegit diffaway. The update recipes below are both built on it.

Start by finding out where you stand:

bash
npm run components:status
  • outdated means canon moved and your copy did not. Reinstall the component by name and you are done:node scripts/install-components.mjs hero.
  • modified means you changed it and canon did not. This needs nothing.
  • diverged means both sides moved. That is the case the first recipe exists for.

The content hash covers the template, stylesheet, script and any modules. It deliberately excludesmanifest.json, so a manifest-only change on either side does not show up in the status report.diff -ruagainst a fresh download is how you see those.

Before editing a component at all, consider whether an override can do the job instead; see Customizing Components Without Editing Them. A component you never touch updates with a plain copy, forever.

Recipe 1: Updating a Component You Have Customized

Sometimes an override is not enough and you edit the component itself. That is allowed; the cost is that adopting a later canon version becomes a merge rather than a copy. Git already knows how to do that merge, and the install commit is what gives it something to merge against.

Four steps. Say you have editedheroand want the current canon version.

1. Find the commit where it was installed

bash
git log --grep="Component-Name: hero" -1 --format=%H

2. Save what you changed since

bash
git diff <install-commit> HEAD -- lib/layouts/components/sections/hero > /tmp/hero.patch

That patch is your fork: every edit you made on top of the version you installed, and nothing else.

3. Reinstall from canon

bash
git status --porcelain -- lib/layouts/components/sections/hero   # must be empty
node scripts/install-components.mjs hero

Naming the component explicitly reinstalls it even though it is already present. The canon files land, and a fresh install commit records the new version. Your edits are gone from the working tree at this point, which is fine, because step 2 has them.

4. Reapply your edits

bash
git apply --3way /tmp/hero.patch

--3waymerges rather than applying blindly, so edits to lines canon did not touch land silently and genuine collisions come back as ordinary conflict markers for you to resolve. Build, check the result, then commit the reapplied customization as its own commit so the next update has a clean baseline to diff from.

If the patch applies cleanly and the component still looks right, you are done. If it conflicts, the conflict is the useful part: it is the exact place where canon changed something you had also changed.

Recipe 2: Components Installed Before Install Commits Existed

Components installed by hand, or by the per-componentinstall.shscripts, have no install commit to diff against. There is no baseline in your history, so make one from canon instead. This recipe matters for every site older than the installer.

bash
curl -sO https://nunjucks-components.com/downloads/partials/text.zip
unzip -q text.zip -d /tmp/canon
diff -ru /tmp/canon/text lib/layouts/components/_partials/text

Read that diff in both directions. Lines only in your copy are your customizations. Lines only in canon are improvements you never received, which is the part that is easy to miss.

Decide file by file: a manifest is usually safe to take wholesale, while CSS you have edited deserves a real merge. Commit the result with the same trailers the installer writes, so the next update has a baseline:

text
component: update text@1.3.2 from nunjucks-components.com

Component-Name: text
Component-Version: 1.3.2
Content-Hash: bdce80ff48392bc5

versionandcontentHashcome from the catalog at /downloads/manifest.json, whereversionis the library release andcontentHashidentifies this component's content. Once that commit exists, the component is a first-class citizen ofcomponents:status, and the next update follows Recipe 1.

Verifying an Update

After either recipe, the verification is the same: build the site and look at the result.

bash
npm run build

For a component whose update was meant to be invisible, the build is the artifact. Diff the output tree against a build from before the update; nothing should change unless the update was meant to change it.

For CSS changes specifically, screenshots are how you convince yourself but not how you find out. Load the affected pages before and after, ask the browser for computed styles on a fixed set of elements, and compare those. Subtle regressions survive a side-by-side look and do not survive a computed-style diff.

Finally, runnpm run components:statusonce more. The component you just updated should report clean, and the trailer of its new install or update commit is the baseline the next update will diff against.