Weaverse LogoWeaverse
All ArticlesPaul Phan
3 mins read

Using Shopify CLI for Bulk Operations (New Feature)

Using Shopify CLI for Bulk Operations (New Feature) Shopify CLI 3.90.1 introduces powerful new commands that let you execute Admin API queries, mutations, and bulk operations directly from your termin
#devops#shopify#shopify-development
Using Shopify CLI for Bulk Operations (New Feature)

Using Shopify CLI for Bulk Operations (New Feature)

Shopify CLI 3.90.1 introduces powerful new commands that let you execute Admin API queries, mutations, and bulk operations directly from your terminal.

This is a game-changer for developers who need to script and automate data operations without building custom tooling.

New Commands

Standard API Queries

shopify app execute 'query { shop { name } }'

Run any GraphQL query or mutation against the Admin API.

Bulk Operations

# Start a bulk query
shopify app bulk execute 'query { products(first: 1000) { edges { node { id title } } } }'
# Watch progress synchronously
shopify app bulk execute 'query { ... }' --watch
# Check status of running operation
shopify app bulk status
# Cancel an operation
shopify app bulk cancel

Why This Matters

Before: Bulk operations required:

  • Custom scripts with polling logic
  • Error handling for long-running jobs
  • Complex state management

Now:

  • One CLI command
  • Optional --watch flag makes it synchronous
  • Perfect for automation and scripting

Practical Use Cases

1. Data Migration

Export all products to JSON in one command:

shopify app bulk execute 'query { products(first: 10000) { edges { node { id title handle } } } }' --watch > products.json

2. Bulk Updates

Update pricing across thousands of variants:

shopify app bulk execute 'mutation { productVariantsBulkUpdate(...) { ... } }'

3. AI Coding Agents

This is perfect for AI tools like Cursor, Claude, or GitHub Copilot. They can now query and manipulate dev stores without building custom integrations.

4. Scheduled Scripts

Use in cron jobs for daily operations:

# Daily inventory sync at 6 AM
0 6 * * * shopify app bulk execute 'query { inventoryItems(first: 1000) { ... } }' --watch > /var/log/inventory.json

5. CI/CD Pipelines

Integrate bulk operations into your deployment workflow:

  • Pre-deploy data validation
  • Post-deploy data seeding
  • Automated testing with real data

Pro Tips

  • Use --watch when you need results immediately (scripts, CI/CD)
  • Combine with jq for powerful JSON processing
  • Perfect for one-off fixes without building full apps
  • Great for prototyping bulk operations before implementing in code

Example: Bulk Tag Sync

shopify app bulk execute '
mutation bulkOperationRunMutation(
$mutation: MutationQuery!
$input: BulkOperationInput!
) {
bulkOperationRunMutation(mutation: $mutation, input: $input) {
bulkOperation { id status }
userErrors { field message }
}
}
' --watch

What This Unlocks

This feature removes the friction from bulk operations:

✅ No custom polling scripts ✅ No complex state management ✅ Easy automation with cron/CI ✅ AI agents can work with store data ✅ Quick one-off data fixes

Learn More

For complete documentation, see:

Bottom Line

This is one of those quality-of-life improvements that makes development significantly easier. If you work with Shopify data at scale, add these commands to your toolkit.

Building with Hydrogen? Weaverse helps you ship faster with AI-powered theme development. Get started.

Reactions

Like
Love
Celebrate
Insightful
Cool!
Thinking

Join the Discussion

Continue Reading

More insights from the Weaverse team

Hydrogen 2026.1: What You Need to Know About the API Update

Hydrogen 2026.1: What You Need to Know About the API Update

Hydrogen 2026.1: What You Need to Know About the API Update Shopify released Hydrogen 2026.1.0, aligning with their quarterly API release cycle. Most changes are additive, but there's one breaking change that requires immediate attention if you have custom cart discount logic. The Breaking Change The cartDiscountCodesUpdate mutation now requires the discountCodes argument. Before (Implicit) cartDiscountCodesUpdate(cartId: $cartId) After (Explicit) cartDiscountCodesUpdate( cartId: $cartId discountCodes: [] # Required field ) What Else Changed Hydrogen 2026.1.0 updates both: Storefront API → 2026-01 Customer Account API → 2026-01 This is a quarterly version update aligned with Shopify's API release schedule. Action Items Update packages to Hydrogen 2026.1.0 Search codebase for cartDiscountCodesUpdate mutations Add explicit discountCodes argument to all calls Test cart discount functionality Official Changelogs For complete details, review: Storefront API 2026-01 Changelog Customer Account API 2026-01 Changelog Bottom Line 10-minute fix if you have custom discount code logic. Otherwise, smooth upgrade. The migration is straightforward but critical if your store uses programmatic discount code management. Don't skip testing cart functionality after the upgrade. Building with Hydrogen? Weaverse helps you ship faster with AI-powered theme development. Get started.

By Paul Phan
Read
Migrating from Legacy Customer Accounts in Shopify

Migrating from Legacy Customer Accounts in Shopify

For Theme Developers Remove Legacy Liquid Files Delete these files from your theme: templates/customers/login.liquid templates/customers/register.liquid templates/customers/account.liquid Use the New Web Component <!-- Replace legacy login forms with: --> <shopify-account></shopify-account> The shopify-account web component handles: Login/register flows Password reset Account management Multi-factor authentication For App Developers Use Customer Account UI Extensions If your app interacts with customer accounts, migrate to UI extensions: // extension.toml [[extensions.targeting]] target = "customer-account.profile.block-render" // React extension export default function ProfileBlock() { const { customer } = useApi() return ( <BlockStack> <Text>Loyalty Points: {customer.metafields.loyalty.points}</Text> </BlockStack> ) } Stats: 800+ apps already migrated. Don't get left behind. For Custom Storefronts (Hydrogen) Use Customer Account API import { useCustomerAccount } from '@shopify/hydrogen' export function AccountPage() { const { customer, accessToken, logout } = useCustomerAccount() if (!customer) { return <LoginButton /> } return ( <div> <h1>Welcome, {customer.firstName}</h1> <button onClick={logout}>Sign out</button> </div> ) } Migration Steps Update to Hydrogen 2026.x (includes Customer Account API) Replace legacy auth flows with useCustomerAccount hook Test OAuth flow with new customer accounts Remove legacy session handling code Why Migrate? Feature Legacy New MFA Manual Built-in Passwordless No Yes Single sign-on Limited Full OAuth Session security Basic Enhanced Mobile experience Poor Native Checklist Audit themes for legacy customer templates Replace forms with shopify-account component Update apps to use UI extensions Migrate Hydrogen to Customer Account API Test all auth flows Remove legacy session code Need help migrating? Weaverse can modernize your storefront in days, not months.

By Paul Phan
Read
React Router 7.13.1: URL Masking for Modal PDPs in Hydrogen

React Router 7.13.1: URL Masking for Modal PDPs in Hydrogen

React Router 7.13.1: URL Masking for Modal PDPs in Hydrogen The Problem You want a product quick-view modal that: Opens on top of your collection page Shows a shareable URL (/products/sneakers) Keeps the collection visible in the background Works with deep links and browser history Until now, this required manual backgroundLocation management—a clunky pattern that felt like fighting the framework. The Solution React Router 7.13.1 introduces unstable_mask on <Link>. First-class URL masking for Framework/Data Mode. // routes/collection.tsx export default function Collection({ loaderData }) { return ( <div className="collection-grid"> {loaderData.products.map((product) => ( <Link key={product.id} to={`/collection?product=${product.id}`} // Router state unstable_mask={`/products/${product.handle}`} // Browser URL > <ProductCard product={product} /> </Link> ))} {/* Modal overlay */} {loaderData.modalProduct && ( <dialog open> <ProductQuickView product={loaderData.modalProduct} /> </dialog> )} </div> ) } How It Works Router navigates to /collection?product=123 (internal state) Browser shows /products/sneakers (masked URL) Deep link /products/sneakers works normally (mask stripped on SSR) Back button closes modal, restores collection Detecting Masked State import { useLocation } from 'react-router' function ProductModal() { const location = useLocation() // Are we in a modal context? if (location.unstable_mask) { return <ModalProduct /> } // Direct navigation - full page return <FullProductPage /> } Hydrogen Use Cases Modal PDPs from collection grids Image galleries with shareable URLs Cart quick-edit from checkout Filter previews without navigation Important Notes Marked unstable - API may change before stabilization SPA only - Mask removed during SSR (deep links work normally) Requires React Router 7.13.1+ in your Hydrogen project Upgrade npm install react-router@latest

By Paul Phan
Read

Never miss an update

Subscribe to get the latest insights, tutorials, and best practices for building high-performance headless stores delivered to your inbox.

Join the community of developers building with Weaverse.