shopi-cli
v0.1.0
Published
JSON-first Shopify Admin GraphQL CLI for humans, agents, and CI.
Downloads
166
Maintainers
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
productsororders. - Builds write commands from MutationRoot fields, for example
productCreateormetafieldsSet. - Uses TTY-aware output: tables in terminals, JSON in scripts and pipes.
- Supports
json,table, andmarkdownoutput 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-cliFor local development from this repository:
bun install
bun run shopi --helpYou can also run the binary directly:
./src/cli.ts --helpAuthentication
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 jsonYou can find the client credentials in the Shopify Dev Dashboard:
Dev Dashboard -> Apps -> your app -> Settings -> Client ID / Client secretSHOPIFY_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 \
--validateUse a local repo-scoped profile when you do not want global machine config:
shopi auth login --local --shop your-store --token shpat_xxxScopes
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_translationsSome 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 --prettyRead 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 --prettyPreview the generated operation without calling Shopify:
shopi read products --first 5 --dry-run --json --prettyWrite 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 --prettyFor 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 }' \
--confirmRun 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 --tableCommand reference
Use built-in help as the source of truth:
shopi --help
shopi help auth
shopi help gql
shopi help read
shopi help writeRepo documentation:
Development
bun install
bun run check
bun run buildThe project has no runtime dependencies. Development uses Bun, TypeScript, and
bun test.
License
MIT. See LICENSE.
