Automated SVG Optimization in CI/CD Pipelines
Manual SVG optimization is a habit that breaks down under deadline pressure. The only reliable way to keep your SVG assets optimized is to automate it — run optimization on every change, before it can be forgotten.
Here are three automation patterns: GitHub Actions, GitLab CI, and a pre-commit hook.
GitHub Actions: optimize on pull request
This workflow detects which SVG files changed in a pull request, optimizes them, and commits the result back to the branch:
# .github/workflows/optimize-svgs.yml
name: Optimize SVGs
on:
pull_request:
paths:
- '**.svg'
jobs:
optimize:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.head_ref }}
- uses: actions/setup-node@v4
with:
node-version: 20
- name: Install SVGO
run: npm install -g svgo
- name: Optimize changed SVGs
run: |
git diff --name-only origin/${{ github.base_ref }}...HEAD \
| grep '\.svg$' \
| xargs -I{} svgo --multipass {}
- name: Commit optimized SVGs
uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: 'chore: optimize SVG assets'The workflow only runs when .svg files change, and the auto-commit step only creates a commit if files were actually modified.
GitHub Actions: using the svg.dog API
If you don’t want to install Node.js in CI, use the svg.dog API directly withcurl. Store your API key as a GitHub secret:
# .github/workflows/optimize-svgs-api.yml
name: Optimize SVGs via API
on:
pull_request:
paths:
- '**.svg'
jobs:
optimize:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.head_ref }}
- name: Optimize changed SVGs
env:
SVGDOG_API_KEY: ${{ secrets.SVGDOG_API_KEY }}
run: |
for file in $(git diff --name-only origin/${{ github.base_ref }}...HEAD | grep '\.svg$'); do
curl -s -X POST https://api.svg.dog/v1/optimize \
-H "Authorization: Bearer $SVGDOG_API_KEY" \
-F "file=@$file" \
-o "$file.tmp" \
&& mv "$file.tmp" "$file"
done
- name: Commit optimized SVGs
uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: 'chore: optimize SVG assets'GitLab CI
Similar approach in GitLab’s pipeline format:
# .gitlab-ci.yml
optimize-svgs:
stage: build
image: node:20-alpine
rules:
- changes:
- "**/*.svg"
before_script:
- npm install -g svgo
script:
- |
git diff --name-only origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME...HEAD \
| grep '\.svg$' \
| xargs -I{} svgo --multipass {}
- git config user.email "ci@example.com"
- git config user.name "CI Bot"
- git add -A
- git diff --staged --quiet || git commit -m "chore: optimize SVG assets"
- git pushPre-commit hook
For individual developers, a pre-commit hook optimizes staged SVG files before every commit. Use husky and lint-staged:
npm install --save-dev husky lint-staged svgo
npx husky init// package.json
{
"lint-staged": {
"*.svg": "svgo --multipass"
}
}# .husky/pre-commit
npx lint-stagedNow every time a developer commits an SVG, it’s automatically optimized before the commit is created.
Reporting savings in CI
Add a step that logs how much was saved. Using the svg.dog API makes this easy — theX-Savings-Percent header is returned per file:
for file in $(git diff --name-only | grep '\.svg$'); do
savings=$(curl -s -o /dev/null -X POST https://api.svg.dog/v1/optimize \
-H "Authorization: Bearer $SVGDOG_API_KEY" \
-F "file=@$file" \
-w '%header{x-savings-percent}')
echo "$file: saved $savings%"
doneWhich approach to use
- Small team, GitHub: the GitHub Actions workflow with auto-commit is the easiest to set up and requires no developer action.
- Large team: the pre-commit hook keeps optimization on the developer’s machine and doesn’t require CI write permissions.
- Non-Node.js project: use the API-based workflow — no Node.js installation in CI.
For bulk optimization outside CI, see batch SVG optimization.
Optimize SVGs instantly — no setup needed
500 free optimizations per month. No credit card required.
Get a free API key →