Direct Answer
Yes, Jekyll provides a native configuration directive called keep_files in _config.yml to preserve specific files or directories inside the destination folder (default _site) across builds. However, the destination directory is fundamentally ephemeral: a full build deletes and recreates it entirely before writing new output, and keep_files only exempts listed paths from that initial cleanup. It does not protect against jekyll clean, external tooling, or name collisions with newly generated output.
How keep_files Works (Confirmed Behavior)
- Scope: Paths are relative to the destination root (
_site/), not the project root. Example: keep_files: ["assets/images", "CNAME", ".git"] preserves _site/assets/images/, _site/CNAME, and _site/.git/.
- Mechanism: During the pre-build cleanup phase, Jekyll skips deletion for any entry matching a
keep_files path. All other content is removed.
- Overwrite behavior: If a preserved file shares a name with a newly generated output file, the new output wins.
keep_files prevents deletion, not overwriting.
- Version parity: Jekyll 3.x and 4.x behave identically; no version-specific differences are documented.
Documented Limits
- Ephemeral by design: The destination folder is not a persistent workspace. Any file not listed in
keep_files is guaranteed to disappear on the next full build.
- No protection from
jekyll clean: Running jekyll clean deletes the entire destination directory, including keep_files entries.
- No protection from external tools: CI pipelines, deployment scripts, or manual
rm -rf _site bypass keep_files entirely.
- Incremental mode caveats:
--incremental still honors keep_files for the initial cleanup, but incremental regeneration is considered experimental and may not reliably preserve non-Jekyll-generated assets in edge cases.
- Performance cost: Large or numerous
keep_files entries slow the cleanup phase because Jekyll must compare each entry before deleting.
- No other native controls:
exclude and include in _config.yml affect source-file processing only; they do not influence destination persistence.
Recommended Pattern for External Assets
If you have assets generated by external scripts or manual processes that must appear in the final site, the documented best practice is:
- Keep those assets in the source tree (e.g.,
assets/, static/, or a custom folder) so Jekyll copies them during the normal build.
- Or, use a post-build deployment script that merges the generated
_site with external assets, rather than relying on keep_files to survive inside the ephemeral destination.
Verification Steps
- Add
keep_files: ["preserved"] to _config.yml.
- Create
_site/preserved/test.txt manually.
- Run
jekyll build and confirm _site/preserved/test.txt remains.
- Run
jekyll clean and observe the entire _site directory (including preserved/) is removed.
One Diagnostic Detail
What type of files are you trying to preserve—static assets (images, PDFs), generated reports, or something else? The answer determines whether keep_files is appropriate or if moving them into the source tree is the simpler, more reliable approach.