npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

shopi-cli

v0.1.0

Published

JSON-first Shopify Admin GraphQL CLI for humans, agents, and CI.

Downloads

166

Readme

shopi-cli

shopi is a JSON-first Shopify Admin GraphQL CLI for store owners, operators, developers, agents, and CI jobs. It is intentionally thin over Shopify Admin GraphQL: exact GraphQL documents are supported, and every live QueryRoot and MutationRoot field can be discovered and addressed through schema introspection.

This project is open source under the MIT license and is not affiliated with, endorsed by, or sponsored by Shopify Inc. Shopify is a trademark of Shopify Inc.

What it does

  • Stores local or global Shopify Admin API profiles.
  • Runs exact Admin GraphQL documents with variables from JSON files or stdin.
  • Lists and inspects all live Admin GraphQL query and mutation entry points.
  • Builds read commands from QueryRoot fields, for example products or orders.
  • Builds write commands from MutationRoot fields, for example productCreate or metafieldsSet.
  • Uses TTY-aware output: tables in terminals, JSON in scripts and pipes.
  • Supports json, table, and markdown output explicitly.
  • Keeps write operations guarded with --confirm.

shopi cannot bypass Shopify access scopes. Your app must be installed with the read or write scopes required by the operation you run.

Install

bun add -g shopi-cli

For local development from this repository:

bun install
bun run shopi --help

You can also run the binary directly:

./src/cli.ts --help

Authentication

For Dev Dashboard apps installed on your own store, put the shop, client ID, and client secret in your environment. shopi exchanges those credentials for a short-lived Admin API access token when it runs.

export SHOPIFY_SHOP=your-store.myshopify.com
export SHOPIFY_CLIENT_ID=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
export SHOPIFY_CLIENT_SECRET=shpss_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
export SHOPIFY_API_VERSION=2026-04

shopi auth status --validate --output json

You can find the client credentials in the Shopify Dev Dashboard:

Dev Dashboard -> Apps -> your app -> Settings -> Client ID / Client secret

SHOPIFY_ACCESS_TOKEN=shpat_... is still supported as an explicit fallback, but client credentials are the preferred env-based flow.

You can also save a profile with an already-issued Admin API access token:

shopi auth login \
  --shop your-store.myshopify.com \
  --token shpat_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \
  --profile production \
  --validate

Use a local repo-scoped profile when you do not want global machine config:

shopi auth login --local --shop your-store --token shpat_xxx

Scopes

Use the narrowest scope set that covers your workflow. For broad shop operations with this CLI, this scope string worked against the test shop:

read_assigned_fulfillment_orders,write_assigned_fulfillment_orders,read_customers,write_customers,read_price_rules,write_price_rules,read_discounts,write_discounts,write_draft_orders,read_draft_orders,read_files,write_files,read_fulfillments,write_fulfillments,write_inventory,read_inventory,read_legal_policies,read_locales,write_locales,write_locations,read_locations,write_marketing_events,read_marketing_events,read_markets,write_markets,read_merchant_managed_fulfillment_orders,write_merchant_managed_fulfillment_orders,read_metaobject_definitions,write_metaobject_definitions,read_metaobjects,write_metaobjects,read_online_store_pages,write_order_edits,read_order_edits,read_orders,write_orders,read_products,write_products,read_reports,read_returns,write_returns,read_shipping,write_shipping,read_content,write_content,read_themes,write_themes,read_third_party_fulfillment_orders,write_third_party_fulfillment_orders,read_translations,write_translations

Some Shopify scopes require approval, a specific app type, Shopify Plus, or a specific extension flow. Do not add scopes Shopify rejects during app release; add them only when your app is eligible for them.

First commands

shopi version
shopi auth status --validate
shopi gql --query '{ shop { name myshopifyDomain } }'
shopi schema pull
shopi ops list --kind query --filter product
shopi ops show productCreate --kind mutation --output json --pretty

Read from any QueryRoot field

shopi read loads the live Admin schema, validates the root field and arguments, then builds a GraphQL query.

shopi read products --first 10 --select 'nodes { id title handle status }'
shopi read orders --first 25 --query 'financial_status:paid' --output json
shopi read product --id gid://shopify/Product/1234567890 --json --pretty

Preview the generated operation without calling Shopify:

shopi read products --first 5 --dry-run --json --pretty

Write to any MutationRoot field

shopi write uses the same live schema but targets MutationRoot. It refuses to execute unless you pass --confirm.

shopi write productCreate \
  --input @examples/product-create.json \
  --select 'product { id title handle } userErrors { field message }' \
  --confirm \
  --json --pretty

For mutations with multiple arguments, pass them explicitly:

shopi write metafieldsSet \
  --arg metafields=@examples/metafields-set.json \
  --select 'metafields { id key namespace value } userErrors { field message }' \
  --confirm

Run exact GraphQL

shopi gql --file examples/shop-info.graphql --json --pretty
shopi gql --file examples/products-list.graphql --variables '{"first": 10}'
shopi gql --file examples/product-create.graphql --variables '{"product":{"title":"Example"}}' --confirm
shopi gql --file mutation.graphql --variables @variables.json --full

--full includes GraphQL extensions such as cost data. Without it, shopi prints only data.

Output

Interactive terminals default to table. Pipes and CI default to json. Override with:

shopi read products --first 10 --output json --pretty
shopi read products --first 10 --output markdown
shopi read products --first 10 --table

Command reference

Use built-in help as the source of truth:

shopi --help
shopi help auth
shopi help gql
shopi help read
shopi help write

Repo documentation:

Development

bun install
bun run check
bun run build

The project has no runtime dependencies. Development uses Bun, TypeScript, and bun test.

License

MIT. See LICENSE.