Commit the generated code when you want every change reviewed, and generate at build time when you can pin the tool and trust the pipeline. For most teams the safer default is to commit it and have CI check that regeneration produces no difference.
The two approaches
Commit generated code. The output lives in your repository. Pull requests show exactly what changed in the client.
Generate at build time. Only the spec and configuration are committed. The pipeline runs the generator and builds from the result. Nothing generated is stored.
Comparison
| Question | Commit it | Generate at build |
|---|---|---|
| Can reviewers see the real client code? | Yes | No, unless they run the tool |
| Does the build need the generator installed? | No | Yes, so it must be pinned and available |
| Can a tool change alter shipped code unseen? | Not without a diff | Yes, if unpinned |
| Repository size and noisy diffs | Larger, noisier | Small |
| Dependency scanners see the code | Yes, in the tree | Only if scan runs after generation |
| Hand edits possible | Yes, but get overwritten | No |
Security points that tip the choice
Visibility. Scanners and reviewers read what is in the repository. If generated files are absent, a scan of the repo misses the libraries the generated project declares. Our post on lockfile scan or built artifact scan shows why timing matters.
Tool trust. Generating at build time means the generator, its templates and any post-process command run in the pipeline on every build. That adds an execution path to protect. See what the post-process option runs.
Drift. With committed code, hand edits creep in. With build time generation they cannot, which keeps the output honest.
A hybrid that works well
- Commit the spec, the config file and the generated output.
- Pin the generator version in one place.
- In CI, regenerate into a temporary directory and compare with the committed tree. Fail on any difference.
- Treat a failure as one of three things: the spec changed without regenerating, someone hand edited a generated file, or the tool version moved.
- Scan the committed tree for vulnerable dependencies as you would any code.
This keeps reviewability while removing most chance of silent change.
When to generate at build time instead
Choose it if the generated code is large and never edited, the toolchain is already pinned and mirrored, and you scan after generation. It suits internal clients where noisy diffs cost more than they give.
When the client is published to others
If you publish the SDK for customers, committing and reviewing the output matters more. The workflow docs describe a helper script for pushing an auto generated SDK to a GitHub repository. Review what it will push before you run it, since the result is code your customers install.
Where Safeguard fits
Safeguard generates SBOMs and scans dependencies for the repository, with reachability analysis to show which vulnerable libraries your code can actually reach, whichever way you handle generated code.
Try it yourself
Click through it at your own pace, or open it full screen. Look at how the list shrinks once unreachable findings are set aside.
Quick check
Is a CI regeneration check worth the effort?
Yes. It is a few lines in a pipeline and catches tool drift and stray hand edits.
Sources
Last reviewed: 19 October 2026.