Automated SVG Optimization in CI/CD Pipelines

·7 min read

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 push

Pre-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-staged

Now 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%"
done

Which 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 →