Project structure
How an Open Assets project is laid out on disk, from assets.json and template folders to public, dist, exports, assets.lock and localizations.json files.
Open Assets only requires one file: assets.json. Everything else is a convention you can change, because every path is set in the manifest. This is the layout the README and the example projects use.
assets.json
The manifest. It lists collections, their templates and their export sizes. Commands look for it in the project directory (the [dir] argument, default .). Use --config <path> or OPEN_ASSETS_CONFIG for a different filename. Full schema: Manifest reference.
Template folders
Templates are HTML or SVG files. Their location is up to you: each templates[].src is a path relative to the project directory. The examples use assets/; open-assets init scaffolds into src/. Either works.
Keep per-collection helper files (like the _shared.css that the Skimmer example puts next to its screenshots) beside the templates and link them relatively.
public/
Shared files referenced by many templates: logos, background photos, fonts, app screenshots captured by UI tests. Set it with the root publicDir field. The dev server serves it and watches it for changes. See The public directory.
src/ and dist/ (optional)
Projects that use Tailwind keep the Tailwind input in src/styles.css (or assets/styles.css) and compile it to dist/styles.css, which templates link. Open Assets does not compile CSS itself; run the Tailwind CLI next to it. See Setup.
exports/
Rendered images. render writes to ./exports by default, relative to the directory you run it from; change it with -o. Layout:
- One template in a collection:
exports/<collection>/<size>.png. - Two or more templates:
exports/<collection>/<size>/<template>.png. - With localizations, a locale level is inserted:
exports/<collection>/<locale>/.... - Entries with
outFilewrite wherever you point them instead.
Details in Outputs.
assets.lock
Written by render. It stores a checksum per template and per output so unchanged images are skipped next time. Commit it so teammates and CI share the cache. See The lockfile.
localizations.json (optional)
Translated strings for templates that use {{key}} placeholders. A collection points to it with its localizations field. See Localization.
.gitignore
open-assets init writes:
dist/
exports/
node_modules/The example projects ignore the same folders (plus outputs/). Ignoring exports/ treats images as build output that anyone can regenerate. If you would rather review images in pull requests or upload them from the repo, remove exports/ from the list and commit them. Keep in mind that the lockfile skips an image only when the output file exists on disk, so a fresh clone without committed exports re-renders everything once.
Monorepo placement
The marketing project usually sits in its own folder (for example marketing/) next to your app. Paths like an Xcode output path or an outFile are resolved from the project directory, so ../MyApp/... reaches sibling folders.
Next steps
Last updated on
Tutorial: your first screenshot set
Build a three-screenshot App Store set with a shared stylesheet, render it at iPhone 6.9 and 6.7 inch sizes, and write an app icon into an Xcode asset catalog.
Shell alias and editor setup
Shorten the Open Assets command with a shell alias, add npm scripts for dev and render with Tailwind, and set up your editor and gitignore for a smooth loop.