Manual Shopify theme deployment is error-prone. Developers download the theme, make changes locally, and upload via the Shopify admin or CLI. There is no audit trail, no automated quality checks, and no safe way to roll back if something goes wrong. For stores with multiple developers, this becomes even more problematic — overwriting each other’s changes is a regular occurrence.
CI/CD (Continuous Integration / Continuous Deployment) pipelines solve these problems. Every change goes through version control, automated checks run before deployment, and deployments are predictable and repeatable. This guide covers how we implement CI/CD for Shopify themes across our Shopify development projects.
Why CI/CD for Shopify themes
The benefits of automated deployment compound over time:
- Consistency — every deployment follows the same process, eliminating human error.
- Quality gates — linting, accessibility checks, and performance audits run automatically.
- Audit trail — Git history provides a complete record of who changed what and when.
- Collaboration — multiple developers work on branches, review each other’s code, and merge without conflicts.
- Rollback capability — deploying a previous commit is a one-click operation.
- Speed — automated deployment takes 2 minutes versus 15 minutes of manual uploading.
Once you have used CI/CD for Shopify theme deployment, going back to manual deployment feels like going back to dialup internet. The investment in setup pays for itself within the first month.

Prerequisites and setup
Before setting up CI/CD, you need:
- A Git repository (GitHub, GitLab, or Bitbucket) containing your theme code.
- Shopify CLI installed and configured in your CI environment.
- A Shopify store with a custom app that has
write_themesscope for API-based deployment. - Theme IDs for your staging and production themes.
Creating deployment credentials
# In Shopify Admin > Settings > Apps and sales channels > Develop apps
# Create a custom app with these scopes:
# - write_themes (required for theme deployment)
# - read_themes (required for theme listing)
# Store these as GitHub repository secrets:
# SHOPIFY_STORE_URL: your-store.myshopify.com
# SHOPIFY_ACCESS_TOKEN: shpat_xxxxxxxxxxxxxxxx
# SHOPIFY_STAGING_THEME_ID: 123456789
# SHOPIFY_PRODUCTION_THEME_ID: 987654321
GitHub Actions workflow
Here is a complete GitHub Actions workflow that lints, tests, and deploys a Shopify theme:
# .github/workflows/deploy.yml
name: Deploy Shopify Theme
on:
push:
branches: [main, staging]
pull_request:
branches: [main]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Shopify CLI
run: npm install -g @shopify/cli @shopify/theme
- name: Run Theme Check
run: shopify theme check --fail-level error
deploy-staging:
needs: lint
if: github.ref == 'refs/heads/staging'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Shopify CLI
run: npm install -g @shopify/cli @shopify/theme
- name: Deploy to staging theme
env:
SHOPIFY_CLI_THEME_TOKEN: ${{ secrets.SHOPIFY_ACCESS_TOKEN }}
SHOPIFY_FLAG_STORE: ${{ secrets.SHOPIFY_STORE_URL }}
run: |
shopify theme push --theme ${{ secrets.SHOPIFY_STAGING_THEME_ID }} --allow-live
deploy-production:
needs: lint
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
environment: production
steps:
- uses: actions/checkout@v4
- name: Install Shopify CLI
run: npm install -g @shopify/cli @shopify/theme
- name: Deploy to production theme
env:
SHOPIFY_CLI_THEME_TOKEN: ${{ secrets.SHOPIFY_ACCESS_TOKEN }}
SHOPIFY_FLAG_STORE: ${{ secrets.SHOPIFY_STORE_URL }}
run: |
shopify theme push --theme ${{ secrets.SHOPIFY_PRODUCTION_THEME_ID }} --allow-live
Automated linting with Theme Check
Theme Check is Shopify’s official linter for Liquid themes. It catches syntax errors, performance issues, accessibility problems, and deprecated patterns before they reach production:
# Run Theme Check locally
shopify theme check
# Run with specific severity threshold
shopify theme check --fail-level error # Only fail on errors
shopify theme check --fail-level warning # Fail on warnings too
# Configuration via .theme-check.yml
# .theme-check.yml
extends: :theme_app_extension
RemoteAsset:
enabled: true
severity: error
ImgWidthAndHeight:
enabled: true
severity: warning
UnusedAssign:
enabled: true
severity: suggestion
Branch strategy for Shopify themes
A clean branching strategy prevents conflicts and ensures code quality. Our recommended approach mirrors the theme development workflow:
- main — production-ready code. Deploys automatically to the live theme.
- staging — integration branch. Deploys to an unpublished staging theme for QA.
- feature/* — individual feature branches. Created from staging, merged back via pull request.
- hotfix/* — emergency fixes. Created from main, merged to both main and staging.
Staging environments
Shopify supports unpublished themes that serve as staging environments. Deploy feature branches to unpublished themes for testing before merging:
# Create a new unpublished theme for testing
shopify theme push --unpublished --json
# The command returns the theme ID and preview URL
# Share the preview URL with stakeholders for review

Managing .shopifyignore
The .shopifyignore file controls which files are excluded from deployment. This is critical for preventing merchant customisations from being overwritten:
# .shopifyignore
config/settings_data.json # Merchant customisations - never deploy
templates/*.json # Optional: preserve merchant template changes
*.md # Documentation files
.github/ # CI configuration
.theme-check.yml # Linter configuration
node_modules/ # Dependencies
package.json # npm configuration
Safe production deployment
Production deployment should always follow a stage-then-publish pattern:
- Deploy code to an unpublished theme (staging).
- Test the staging theme using the preview URL.
- Run automated tests (Lighthouse CI, visual regression).
- If all tests pass, deploy the same code to the production theme.
- Verify the production deployment via spot checks.
Rollback strategies
If a production deployment introduces issues, you need to roll back quickly:
# Option 1: Deploy the previous commit
git revert HEAD
git push origin main # Triggers CI/CD to deploy the reverted code
# Option 2: Deploy a specific commit
git checkout abc123 # Known good commit
shopify theme push --theme $PRODUCTION_THEME_ID --allow-live
# Option 3: Use Shopify's theme duplication
# Before each deployment, duplicate the live theme as a backup
# If something goes wrong, publish the backup theme instantly
Advanced pipeline patterns
Visual regression testing
# Add visual regression testing to your pipeline
- name: Run visual regression tests
run: |
npx percy snapshot --config percy.config.js \
--base-url "https://${{ secrets.SHOPIFY_STORE_URL }}?preview_theme_id=${{ secrets.SHOPIFY_STAGING_THEME_ID }}"
Lighthouse CI for performance monitoring
# Lighthouse CI integration
- name: Run Lighthouse CI
run: |
npm install -g @lhci/cli
lhci autorun --config=lighthouserc.json

CI/CD for Shopify themes is no longer optional for professional Shopify development. The setup investment is modest — typically 4–8 hours — and the long-term benefits in reliability, speed, and confidence are transformative. Paired with proper theme architecture and accessibility compliance, automated deployment creates a development workflow that scales with your business. Get in touch if you need help setting up CI/CD for your Shopify themes.
