The lockfile
How assets.lock makes renders incremental: what is checksummed, which changes trigger a re-render, what does not, when to use --force and why to commit it.
open-assets render keeps a file called assets.lock in the project directory. It records what each output was rendered from, so the next run skips images whose inputs have not changed.
Done. 0 asset(s) rendered, 11 skipped (unchanged) in 0.0s.What is in it
{
"version": 1,
"assets": {
"screenshots/01-hero": {
"exports/screenshots/iphone-6.9/01-hero.png": {
"sourceChecksum": "sha256:03d1...",
"outputPath": "exports/screenshots/iphone-6.9/01-hero.png",
"exportedAt": "2026-10-28T18:57:53.222Z",
"exportChecksum": "sha256:543e..."
}
}
}
}- The asset key is
<collection>/<template>, or<collection>/<locale>/<template>when localized. - Each output is keyed by its path, relative to the project directory, so the file is portable across machines.
sourceChecksumhashes the template and its direct local dependencies.exportChecksumhashes the export settings: width, height,outFileand locale.
When an image is skipped
An output is skipped only if all of these hold:
- The lockfile has an entry for that asset and output path.
- The current source checksum matches
sourceChecksum. - The current export checksum matches
exportChecksum. - The recorded
outputPathmatches. - The output file exists on disk.
Anything else re-renders it. So a deleted PNG is regenerated, and changing a size or an outFile re-renders that size.
What the source checksum covers
For an .html template, the checksum includes the file plus every local file it references directly through src="...", href="..." or url(...). A path counts if it resolves, relative to the template's folder, to a file that exists. http(s)://, //, data: and # references are ignored.
That means these changes do trigger a re-render:
- Editing the template.
- Editing a stylesheet it links, such as
../../public/styles.cssor../../dist/styles.css. - Replacing an image it references, such as
../../public/screenshots/01-home.png.
These do not:
- Files referenced from inside a stylesheet (fonts or images in a CSS
url()in an external.cssfile). Only the template's own text is scanned. - Root-relative references like
/logo.png. They resolve against the filesystem root, not your project. - Files a script loads or a URL built at runtime, such as the Skimmer example's locale image swap.
- Remote assets (Google Fonts, CDNs).
localizations.json. Changing a string does not invalidate the cache.sourceSize,backgroundand the renderer's version.
For .svg templates only the SVG file itself is hashed.
--force
npx open-assets render --forceIgnores the cache and renders everything selected (it still updates the lockfile). Use it after changing something the checksum does not see: a translation, a font, a nested CSS asset, a sourceSize, or after upgrading Open Assets.
Other behavior
- A missing or invalid
assets.lockis treated as empty: everything renders and a fresh file is written. - The lockfile is saved even when a render fails mid-run, so finished images stay cached.
- Output actions (
xcode,copy-source) are not cached; they run on every render. - The dev server does not read or write the lockfile.
Commit it
Commit assets.lock so teammates and CI share the cache. Remember that condition 5 requires the output file to exist: a fresh checkout where exports/ is gitignored will render everything once, then stay incremental. outFile destinations that you commit (like public/favicon.png) are skipped right away.
Related
Last updated on
Tags
Tags group collections so you can render or list a subset with --tag. Learn how root tag definitions and collection tags relate, and how init generates them.
The public directory
How publicDir holds shared logos, photos, fonts and UI test captures, how the dev server serves and watches it, and how to reference it so render resolves.