Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
40rty-ai avatar

Shopify Admin Variant Performance Report

  • 3 installs
  • 173 repo stars
  • Updated June 26, 2026
  • 40rty-ai/shopify-admin-skills

shopify-admin-variant-performance-report is a Claude Code skill that ranks every product variant by revenue, units and refund rate and cross-references current inventory.

About

A Claude Code skill that ranks individual Shopify variants by revenue, units sold, and refund rate over a date range, then joins the results against live inventory levels. It computes revenue per inventory unit to surface variants tying up shelf capital and flags unsold variants as dead-stock candidates. Merchants use it for SKU-level merchandising decisions.

  • Ranks every variant by revenue, units sold, and refund rate over a date range
  • Joins order data against live inventory to flag dead-stock candidates
  • Read-only; computes revenue-per-inventory-unit to spot low-earning SKUs

Shopify Admin Variant Performance Report by the numbers

  • 3 all-time installs (skills.sh)
  • Ranked #1,816 of 2,715 Automation & Workflows skills by installs in the Skillselion catalog
  • Data as of Aug 1, 2026 (Skillselion catalog sync)
At a glance

shopify-admin-variant-performance-report capabilities & compatibility

Free; requires an authenticated Shopify CLI session with read_orders and read_products.

Capabilities
variant ranking · dead stock detection · revenue report
Use cases
data analysis
Runs
Runs locally
Pricing
Free
From the docs

What shopify-admin-variant-performance-report says it does

Rank every product variant by revenue, units sold, and refund rate, then cross-reference against current inventory to identify dead weight vs. top performers.
SKILL.md
variants present in inventory but with zero sales are flagged as dead stock candidates
SKILL.md
npx skills add https://github.com/40rty-ai/shopify-admin-skills --skill shopify-admin-variant-performance-report

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs3
repo stars173
Last updatedJune 26, 2026
Repository40rty-ai/shopify-admin-skills

What it does

Rank Shopify variants by performance and cross-reference inventory to find dead stock.

Who is it for?

Merchants making SKU-level decisions about top performers versus dead stock.

Skip if: Product-level summaries; use the top product performance report for that.

When should I use this skill?

You need variant-level revenue and inventory insight to cut or reorder SKUs.

What you get

A variant ranking with inventory join, dead-stock flags, and revenue-per-inventory-unit.

  • Top and bottom variant ranking (human or JSON)

By the numbers

  • 2 GraphQL query operations (orders + productVariants)
  • default top_n 30 variants
  • default min_units 1

Files

SKILL.mdMarkdownGitHub ↗

Purpose

Goes beyond product-level revenue by ranking every individual variant (size, color, option combination) on revenue, units sold, and refund rate, then joining against live inventory levels. Reveals which specific SKUs are driving the business and which are tying up capital on the shelf. Read-only — no mutations are executed.

Prerequisites

  • Authenticated Shopify CLI session: shopify auth login --store <domain>
  • API scopes: read_orders, read_products (validator-confirmed: orders query traverses variant→product graph)

Parameters

ParameterTypeRequiredDefaultDescription
storestringyesStore domain (e.g., mystore.myshopify.com)
formatstringnohumanOutput format: human or json
dry_runboolnofalsePreview operations without executing mutations
date_range_startstringyesStart date in ISO 8601 (e.g., 2025-01-01)
date_range_endstringyesEnd date in ISO 8601 (e.g., 2025-01-31)
top_nintegerno30Number of top and bottom variants to display
sort_bystringnorevenueRanking metric: revenue, units, or refund_rate
min_unitsintegerno1Exclude variants with fewer than N units sold in the period

Workflow Steps

1. OPERATION: orders — query Inputs: first: 250, query: "created_at:>='<date_range_start>' created_at:<='<date_range_end>'", pagination cursor; select lineItems with variant { id, sku, title, selectedOptions }, quantity, originalTotalSet; and refunds.refundLineItems with variant id and subtotalSet Expected output: All orders in range; paginate until hasNextPage: false; aggregate in-memory per variant.id: units sold, gross revenue, refunded units, refunded amount, refund rate

2. OPERATION: productVariants — query Inputs: List of variant IDs collected in step 1, first: 250, pagination cursor; select id, sku, title, selectedOptions, inventoryQuantity, product { id, title }, price Expected output: Current inventory levels and metadata for each sold variant; joined with step-1 aggregates; variants present in inventory but with zero sales are flagged as dead stock candidates

3. In-memory computation: Sort merged dataset by sort_by metric; compute revenue-per-inventory-unit ratio (net revenue ÷ inventory quantity) to highlight variants earning little relative to shelf space; split output into top-N performers and bottom-N by the same metric

GraphQL Operations

# orders:query (variant line items + refunds) — validated against api_version 2025-01
query OrdersForVariantPerformance($first: Int!, $after: String, $query: String) {
  orders(first: $first, after: $after, query: $query) {
    edges {
      node {
        id
        createdAt
        lineItems(first: 50) {
          edges {
            node {
              quantity
              originalTotalSet {
                shopMoney { amount currencyCode }
              }
              variant {
                id
                sku
                title
                selectedOptions { name value }
                product { id title }
              }
            }
          }
        }
        refunds {
          refundLineItems(first: 50) {
            edges {
              node {
                quantity
                subtotalSet {
                  shopMoney { amount currencyCode }
                }
                lineItem {
                  variant { id }
                }
              }
            }
          }
        }
      }
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}
# productVariants:query (inventory snapshot) — validated against api_version 2025-01
query VariantInventorySnapshot($first: Int!, $after: String, $query: String) {
  productVariants(first: $first, after: $after, query: $query) {
    edges {
      node {
        id
        sku
        title
        price
        selectedOptions { name value }
        inventoryQuantity
        product {
          id
          title
        }
      }
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}

Session Tracking

Claude MUST emit the following output at each stage. This is mandatory.

On start, emit:

╔══════════════════════════════════════════════╗
║  SKILL: variant-performance-report           ║
║  Store: <store domain>                       ║
║  Started: <YYYY-MM-DD HH:MM UTC>             ║
╚══════════════════════════════════════════════╝

After each step, emit:

[N/TOTAL] <QUERY|MUTATION>  <OperationName>
          → Params: <brief summary of key inputs>
          → Result: <count or outcome>

On completion, emit:

For format: human (default):

══════════════════════════════════════════════
OUTCOME SUMMARY
  Orders processed:     <n>
  Variants analysed:    <n>
  Date range:           <start> to <end>
  Sort by:              <metric>
  Errors:               0
  Output:               variant_performance_<date>.csv
══════════════════════════════════════════════

For format: json, emit:

{
  "skill": "variant-performance-report",
  "store": "<domain>",
  "started_at": "<ISO8601>",
  "completed_at": "<ISO8601>",
  "dry_run": false,
  "steps": [
    { "step": 1, "operation": "OrdersForVariantPerformance", "type": "query", "params_summary": "<date_range_start> to <date_range_end>", "result_summary": "<n> orders, <n> variants aggregated", "skipped": false },
    { "step": 2, "operation": "VariantInventorySnapshot", "type": "query", "params_summary": "<n> variant IDs", "result_summary": "<n> variants with inventory data", "skipped": false }
  ],
  "outcome": {
    "orders_processed": 0,
    "variants_analysed": 0,
    "date_range_start": "<date_range_start>",
    "date_range_end": "<date_range_end>",
    "sort_by": "revenue",
    "top_performers": [],
    "dead_weight": [],
    "errors": 0,
    "output_file": "variant_performance_<date>.csv"
  }
}

Output Format

CSV file variant_performance_<YYYY-MM-DD>.csv with one row per variant:

ColumnDescription
product_idShopify product GID
product_titleProduct name
variant_idShopify variant GID
variant_titleOption combination (e.g., "Blue / Large")
skuVariant SKU
units_soldTotal units sold in period
gross_revenueRevenue before refunds
refunded_amountTotal refund value
net_revenueGross minus refunds
refund_rate_pctRefunded units ÷ sold units × 100
inventory_qtyCurrent stock on hand
revenue_per_inventory_unitNet revenue ÷ inventory qty (blank if inventory = 0)

For format: human, two ranked tables are printed inline: 1. Top performers — top top_n variants by sort_by metric 2. Dead weight — bottom top_n variants by revenue_per_inventory_unit (≥ min_units sold, inventory > 0)

Error Handling

ErrorCauseRecovery
THROTTLEDAPI rate limit from paginating large order historyWait 2 s, retry up to 3 times; narrow date range if persistent
variant is null on line itemProduct or variant was deleted after purchaseAggregate by line item title with variant_id: null; still counted in totals
inventoryQuantity is nullVariant uses fulfillment service (no tracked inventory)Record as inventory_qty: null; exclude from revenue-per-unit ratio
No orders returnedNo orders in date rangeWiden date range

Best Practices

1. Run with a 30–90 day window first. Very wide windows produce large pagination chains and slow down step 1 significantly. 2. The revenue_per_inventory_unit column is the sharpest signal for dead weight — a high inventory count with near-zero revenue is a clear markdown candidate. 3. High refund_rate_pct on a specific size or color often points to a fit or quality issue — investigate before reordering that option. 4. Use min_units: 5 to filter out statistical noise from variants with very few sales before making merchandising decisions. 5. Pair with dead-stock-identifier for a broader view of inventory health beyond the sales period captured here.

Related skills

FAQ

How is dead stock flagged?

Variants present in inventory but with zero sales are flagged as dead-stock candidates.

Does it join inventory?

Yes, it queries productVariants for current inventory levels and joins them with sales.

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.