The Tringify CLI is the tringify command for building themes and apps. For themes, it creates a theme from the starter, previews and validates it, adds it to a development store and publishes versions to your theme listing. For apps, it creates the app, starts a project from the app starter, keeps the app's configuration in tringify.app.json and releases versions. It signs in with your Tringify account and is open source at github.com/tringify/cli.
On the approval screen, Tringify’s own tools, including the Tringify CLI, show “Verified by Tringify”. Other tools show “This name was provided by the tool. Tringify hasn’t verified it.” Check the prominent domain as well as the name: it comes from the tool’s client metadata address or its registered return addresses. Local loopback addresses appear as “This computer”. Only continue if you recognize the tool and intended access. The CLI’s server-defined client ID is https://api.tringify.com/oauth/connectors/clients/tringify-cli.
Install#
On macOS or Linux, run:
curl -fsSL https://raw.githubusercontent.com/tringify/cli/main/install.sh | sh
The installer downloads the release for your platform, verifies it against the published SHA256SUMS, and installs tringify in ~/.local/bin. On Windows, run this in PowerShell:
irm https://raw.githubusercontent.com/tringify/cli/main/install.ps1 | iex
It verifies the download the same way, installs tringify.exe in %LOCALAPPDATA%\Programs\tringify and adds that folder to your path; open a new terminal afterwards. Releases cover macOS (Apple silicon and Intel), Linux (x86-64 and ARM64) and Windows (x86-64, which also runs on Windows on Arm). Set TRINGIFY_CLI_VERSION to install a specific release. Run tringify version to confirm.
The CLI is a single program and needs nothing else installed: no Python, Node.js or other runtime. The first time you check, package or preview a theme, it downloads the theme validator (themecheck) and preview renderer (theme-preview-render) from the theme tools release for your platform, verifies them against that release's SHA256SUMS, and keeps them in your user cache folder:
System |
Folder |
|---|---|
macOS |
|
Linux |
|
Windows |
|
The CLI looks for a newer theme tools release at most once a day and keeps working offline with the one it has. Set TRINGIFY_THEME_TOOLS_VERSION to use a specific release, TRINGIFY_THEME_TOOLS_HOME to keep the two programs in another folder, or TRINGIFY_THEME_CHECK and TRINGIFY_THEME_PREVIEW to use copies you already have.
Commands#
Command |
What it does |
|---|---|
|
Signs in to a developer organization in your browser. |
|
Signs in to a store. |
|
Signs out of the developer organization and revokes the CLI's access. |
|
Shows the organization and stores you are signed in to and the access each login currently has. |
|
Lists your organization's development stores and their IDs. |
|
Creates a development store and waits until it is ready. |
|
Creates a theme from the starter theme, or from a local theme folder with |
|
Serves a live preview with sample content and rebuilds when you save a file. A failed edit shows the error and keeps the last good page. |
|
Adds the theme to a store as an unpublished theme, then builds it and uploads it into that theme through the store's code-save door every time you save (validated, render-checked and recorded in the theme's code history). The store's live theme never changes. |
|
Compiles |
|
Validates the compiled theme, as it is, with the same rules used on upload. Run |
|
Builds and validates in a temporary copy and writes an upload-ready ZIP, by default |
|
Prints the sample data a preview page receives. |
|
Prints the theme author contract as JSON: data roots and fields, editor setting types and hosted form actions. |
|
Adds the theme to a store as a new, unpublished theme. The live theme does not change. |
|
Downloads a store theme's published files into a new folder. Without |
|
Downloads the exact package a version of your listing was published with into a new folder. Without |
|
Packages the theme and lists the files publishing would add ( |
|
Lists your organization's theme listings and their IDs. |
|
Creates a free theme listing in your developer organization and prints its ID. |
|
Lists the Theme Store categories, for |
|
Changes a listing's text, category, links, screenshots and style covers; only the parts you pass change. Screenshots and covers are 1280×720 PNG, JPEG or WebP. Passing |
|
Submits the listing for Theme Store review. |
|
Shows what changes compared with the newest published version, asks, then publishes the theme as a new version of the listing. |
|
Lists your organization's apps and their IDs. |
|
Lists the category and subcategory IDs for |
|
Creates an app and prints its ID, handle, client ID and client secret; the secret is shown only once. Sales channel apps need |
|
Creates a project from the app starter: a TypeScript Cloudflare Worker with an embedded admin page, signed webhook handling and Store API calls. It writes the app's configuration to |
|
Writes the app's draft configuration to |
|
Checks |
|
Replaces the app's draft configuration with |
|
Checks the app's blocks with the rules applied when the configuration is pushed: each declaration (mode, pages, surface), and each source compiled as a block that reads only the data its mode allows and writes only the markup app blocks may use. Problems are printed as |
|
Prints the sample data each block receives on a page: the page's sample data cut to the |
|
Serves a local preview of the app's blocks inside a theme, rendered as a store renders them, in the page's app block slot after the theme block named by |
|
Creates a link that installs the app. A private app installs its current draft; a marketplace app installs its published version, or with |
|
Marketplace app: checks the blocks and submits the draft for review as a new version, increasing the part of the version number you name in |
|
Private app: sends the draft as an update to the installed stores you name with |
|
Lists the app's versions, newest first. For a private app, each shows how many stores accepted it, have it waiting or got a later version instead, and its release notes. |
|
Publishes an approved marketplace version so stores can install or update to it. |
|
Shows the app's App Store listing and what it still needs before a marketplace submit. |
|
Changes the App Store listing; only the parts you pass change. The icon is a 512×512 PNG, JPEG or WebP; passing |
|
Saves the Markdown file as the draft of the app's privacy policy, hosted by Tringify. |
|
The same for the app's terms of service. |
|
Saves the |
|
Shows the document's public address, its published version with the date and whether it is live, the submission in review, the draft and the latest review decision. |
|
Sends a signed |
|
Issues a new webhook signing secret. For 72 hours, requests also carry a second signature made with the previous secret; the output says exactly when that stops. |
|
Stops signing requests with the previous webhook signing secret now, instead of when its 72 hours end. |
|
Issues a new client secret. For 72 hours the previous secret keeps working too; the output says exactly when it stops. Rotating again during that time stops the oldest secret at once. The new secret is shown only in the output, or with |
|
Stops accepting the previous client secret now. Run it once the new secret is deployed everywhere, or right away if the previous one was exposed. |
|
Lists webhook deliveries to the app, newest first: lifecycle deliveries, or with |
|
Shows whether the app can be retired and why, then opens its Danger zone in the Developer Portal to confirm. |
|
Shows whether the app can be deleted (only when it was never used), then opens its Danger zone in the Developer Portal to confirm. |
Build an app#
tringify app categories --type standard # category and subcategory IDs (no sign-in needed)
tringify app create --name "My app" --type standard --distribution private
# prints the app ID, handle, client ID and client secret (the secret is shown once)
tringify app init --app APP_ID my-app # project from the app starter
tringify app webhook rotate-key # webhook signing secret for .dev.vars
# edit tringify.app.json: scopes, webhook URL, admin URL, events
tringify app block preview # the example app block in the starter theme
tringify app config check # the platform's checks, without saving
tringify app config push # replaces the app's draft
tringify app install-link --store my-store.mytringify.com
tringify app release # marketplace: a new version; private: an update
The app's handle, its unique name in App Store URLs and the default directory of app init, is made from --name unless you choose it with --handle; it is checked before the app is created and cannot change later. tringify app categories reads a public list, so it works without signing in. --type sales_channel creates a sales channel app and needs --category and --subcategory (listed by tringify app categories --type sales_channel); --distribution marketplace lists it in the App Store. App commands that act on one app take --app ID, or read app_id from tringify.app.json (another file with --file). Run tringify app <command> --help for every flag. For a step-by-step walkthrough, see Build your first app.
tringify app retire and tringify app delete show what applies to the app before anything changes: delete only when it was never used on any store, otherwise retire, with the reasons, and says when some stores could not be checked. Both need the Delete Apps permission (apps:delete; run tringify login again if you signed in before these commands existed). Confirming takes your email code or passkey, so the command opens the app's Danger zone in the Developer Portal to finish. See Retire or delete an app.
tringify app install-link takes its --expires choices and the defaults of --expires (7 days) and --uses (1 install) from the Developer API, so they always match the Developer Portal; an unknown --expires is refused with the list of choices.
For a private app, tringify app release --all sends the draft to every installed store that doesn't have it yet; --store takes a store ID or domain and can be repeated. tringify app versions shows each private version's accepted, waiting and replaced counts and its notes. Both say when some stores could not be reached, so a missing store is never silent. See Releases and install links.
For a marketplace app, tringify app release refuses a version identical to the published (or approved) one, since a version is only for configuration or listing changes, and refuses an incomplete listing: tringify app listing show lists what the listing still needs (icon, a screenshot, a support email, a published privacy policy and terms of service). Write the privacy policy, terms and docs in Markdown in your repository and publish them with app privacy push, app terms push and app docs push; see Privacy, terms and docs for your app. tringify app secret rotate issues a new client secret; the previous one keeps working for 72 hours, and tringify app secret finish-rotation revokes it sooner.
Edit sections in src/sections/<name>/ as body.html, style.css and schema.json, and keep src/.generated-sections.json in version control: it records which compiled files build generated, so removing a section's source also removes its compiled file, and a compiled file you edited by hand is never deleted. If you used the tringify-theme command from the theme tools, each of its commands is available as tringify theme <command> with the same rules and output, on the same theme files.
Publish a version#
Create the listing first, with tringify theme create or in the Developer Portal under Themes; the listing holds the name, pricing and review details. Describe it with tringify theme update and send it for review with tringify theme submit. Then publish from a clean git checkout:
tringify theme listings
tringify theme diff --listing LISTING_ID
tringify theme publish --listing LISTING_ID --version 1.2.0 --notes "New header layout"
diff shows the files that change compared with the newest published version. publish refuses to run when the git work tree has uncommitted or untracked changes, so every version matches a commit. It shows the same comparison and asks before publishing; pass --yes to skip the question, for example in CI. It then packages the theme, uploads and validates it, publishes the version, and adds Source commit: <sha> to its release notes. Add --install-store STORE_ID to also install the new version, unpublished, into one of your organization's development stores. A published version cannot change; publish a new version number for every update, and use tringify theme pull --listing LISTING_ID --version X.Y.Z to get any published version back exactly.
Develop against a store#
tringify store create --name "Theme Lab" --country GB --currency GBP
tringify theme dev --store STORE_ID
theme dev adds the theme to the store's primary storefront as an unpublished theme, then watches your files. Every time you save, it builds the theme and uploads it into that theme through the store's code-save door, usually in a few seconds: the same checks as a theme upload, the code-edit rules (the store's buy, cart, checkout and gift card forms and their fields, the theme editor's reveal listeners, transparent overlay roots that respect [hidden], no focus rings, stable colour scheme IDs) and a render of every page the change touches. Refresh the theme preview in Store Admin to see the change. A change that fails prints the error and changes nothing. Each sync is one change in the theme's code history, so you and the merchant can see and undo it in Store Admin. The theme it uses is remembered in .tringify/dev.json, so the next run continues with the same theme; keep .tringify/ out of git. Use --storefront to choose another storefront and --theme to sync into another theme, such as a copy of a Theme Store theme. A sync into the store's live theme never reaches shoppers directly: it goes to the CLI's pending copy of the live theme, which the merchant reviews and publishes or discards in Store Admin (Online Store › Themes, Theme changes to review). Develop on a theme that is not live.
push adds a separate copy each time it runs. pull downloads a store theme, for example one changed in the Store Admin code editor, into a new folder; the files are compiled, so sections are .vasc files rather than src/ folders.
Add sample products#
A theme can ship a demo catalog: demo/catalog.json and the images in demo/images, the same pack the Theme Store uses for its previews. --with-demo adds it to a development store so you can build against the catalog the theme was designed around. It uploads the images to the store's Media, then creates the products with their options, variants and vendors, priced in the store's currency, and turns each demo collection into a tag on its products and a collection for that tag.
tringify theme dev --store STORE_ID --with-demo
It runs on development stores only. Products and collections whose handle the store already has are left as they are, and only the images of the ones it adds are uploaded, so running it again adds only what is missing and never changes or duplicates anything. Products appear under Products within a minute. The first run with the flag asks you to approve product and file access for that store.
Sign-in and access#
tringify login uses OAuth with PKCE and a one-time listener on 127.0.0.1; your password never passes through the CLI. On the approval screen you choose the developer organization, or the store for login --store, and see exactly what the CLI asks for:
Login |
Access |
|---|---|
Developer organization |
|
Store |
|
The CLI never has more access than your own role, and it follows changes to your role. It cannot make a theme live, delete stores, create paid listings or change pricing, and it retires or deletes an app only after you confirm in the Developer Portal. If you signed in before development store access was added, run tringify login again to use the store commands. Tokens are stored only in your system keychain: the macOS Keychain, Windows Credential Manager, or the Secret Service on Linux (GNOME Keyring or KWallet). Without one, sign-in stops and says so. If the keychain does not answer, for example a locked Secret Service over SSH where it cannot show its unlock prompt, the CLI says it is waiting after a few seconds and stops after two minutes with an explanation instead of hanging. Access tokens last 15 minutes and are refreshed automatically; refresh tokens rotate on every use. Uploads, publishes, installs and new development stores are recorded in your organization's activity log as Connected tool: Tringify CLI.
See and disconnect the CLI in your Tringify account under Connected tools, or run tringify logout. Over SSH, set TRINGIFY_NO_BROWSER=1 and open the printed sign-in URL on a machine that can reach the CLI's 127.0.0.1 listener, for example through port forwarding. AI agents can use the same operations through MCP; see Connect an AI assistant.