@tapcart/tapcart-cli
v2.0.1
Published
The Tapcart CLI is a command-line interface for managing and developing blocks.
Maintainers
Keywords
Readme
Tapcart CLI
The Tapcart CLI is a command-line interface for scaffolding Tapcart projects and developing, previewing, and publishing blocks, global components, and layouts.
tapcart is installed and run as a global binary — commands below are invoked directly (tapcart <command>), not via yarn/npm/npx.
Installation
npm i -g @tapcart/tapcart-cliGet started developing Blocks
- Create your project
cd ~/Desktop # or anywhere on your device
tapcart project create -a <application_id> -p my-test-store
# or run with no flags to be prompted interactively:
tapcart project create-a, --app-id: Your Tapcart App ID, found in the Tapcart Dashboard, on the Settings page, under the "Tapcart CLI API Key" section-p, --folder-path: The name (or path) of the folder to create the project in
This will create a new Tapcart project in a folder named my-test-store (or
whatever you named it), and set up editor IntelliSense for block authoring. The
project consists of:
my-test-store/
|--- tapcart.config.json # This is where the Tapcart CLI stores its configuration
|--- package.json # A minimal project marker (no dependencies to install)
|--- blocks/ # This is where your blocks will be stored
|--- components/ # This is where your global components will be stored
|--- .tapcart/types/ # Generated editor types (see "Editor IntelliSense" below)
|--- jsconfig.json # Wires the generated types into your editorThere's nothing to yarn/npm install — the CLI is a global binary and ships
its own authoring types, so a freshly created project has no dependencies of
its own.
- Authenticate with the Tapcart CLI
You must authenticate with the Tapcart CLI before you can use it. You can do this by running the following command:
tapcart auth loginThis will open a browser window where you can log in to your Tapcart account. After logging in, the CLI will store your authentication token locally, allowing you to use the CLI commands without needing to log in again.
- (Optional) Pull down existing blocks
Now pull down the blocks
tapcart block pull --allYou'll see all your blocks pulled down into new folders. In them, you'll see the following files:
MyBlock/
|--- code.jsx
|--- config.json
|--- manifest.json
|--- manifestConfig.jsoncode.jsx: This is the React component code for the blockconfig.json: This holds high-level metadata about the block, such as itslabelandtags. Each block's label is its unique identifier. Supported fields are:label,tags,dependencies.manifest.json: This holds core config elements for the block, such as configurable CSS elements. This data will be available in the right rail in the dashboard.manifestConfig.json: This holds information about which manifest options are selected.
- Create a new block
tapcart block create HelloWorld- Run the new block (or an existing block that was pulled down)
tapcart dev block HelloWorldThis will open http://localhost:4995 by default. Run tapcart dev with no
target to launch the dev server and pick a block, component, or layout from
a picker in the browser instead.
Make changes to the block in code.jsx and observe the changes in your browser
in real time.
Mock Data
Every project has exactly one mockData.json, at the project root — there is
no per-block or per-component mock data file. tapcart project create,
tapcart block create, and tapcart component create will create it
automatically if it doesn't already exist, and will never overwrite it if it
does.
This single file is read equally when previewing any block, component, or
layout with tapcart dev. Edit it to preview against custom cart, customer,
product, collection, and other app data — the structure should match the
schema at .tapcart/types/mockData.schema.json, which also powers editor
IntelliSense for the file.
How it's served to the dev server
- The dev server exposes a
/mock-dataroute that readsmockData.jsonfrom the project root and returns it as-is (missing or invalid JSON is treated as{}rather than failing the request — the client just falls back to its built-in mocks). - The dev client fetches
/mock-dataonce per session via theuseMockData()hook and shallow-merges the result over the live SDK/bridge variables —{ ...variables, ...mockData }— so any top-level key you set (cart,customer,device,product,collection,wishlists,loyalty,theme,data, …) wins over the corresponding real/placeholder value, and any key you omit falls through untouched. - This merge happens in one place (
useTapcartAdapter) and is shared by every render path — block, component, and layout preview all see the same merged variables, which is why one project-root file is enough.
[!IMPORTANT] The bundled MCP server actively instructs AI coding agents to keep this file up to date without being asked: whenever an agent authors or edits block code that reads
tapcartData,product,collection, or any other scope field, its standing instructions tell it to populate/update the project-rootmockData.json(matchingmockData.schema.json) with realistic values in the same change — not to wait for you to notice a blank/broken local preview and ask for it. If you're driving block development through an MCP-connected agent (Cursor, Windsurf, Claude Code, etc.), you should rarely need to hand- writemockData.jsonyourself; see MCP (Model Context Protocol) below.
Editor IntelliSense
tapcart project create and tapcart block/component create automatically set
up editor IntelliSense — autocomplete and type-checking for useTapcart(),
BlockProps, mockData.json, and @tapcart/mobile-components imports — by
writing .tapcart/types/ and a jsconfig.json into your project.
If IntelliSense stops working (e.g. after pulling an older project, or updating the CLI), refresh it manually:
tapcart types syncMCP (Model Context Protocol)
The Tapcart CLI includes an MCP server intended for AI clients (Cursor, Windsurf, etc.) that can call Tapcart CLI functionality via task-first tools.
[!NOTE] The MCP server's system instructions tell connected agents to treat
mockData.jsonas a standing, proactive responsibility — see Mock Data above — rather than something to only touch when a developer explicitly asks for it.
Running the MCP server
Run the MCP server over stdio:
tapcart mcpNotes:
- The MCP server is long-running and keeps the terminal busy until you stop it (Ctrl+C).
- The MCP server runs in the context of the current working directory. When using MCP tools, pass
projectPathwhen you need to target a specific Tapcart project.
AI client configuration example
When configuring an AI client to launch this MCP server, you generally want the command to be tapcart with args mcp, and set environment variables explicitly:
{
"command": "tapcart",
"args": ["mcp"],
"env": {
"TAPCART_ENV": "production"
}
}Environment defaults
The MCP server (and CLI) use TAPCART_ENV to determine which Tapcart environment to target.
Recommended default:
export TAPCART_ENV=productionSafety guardrails for remote writes
Tools that perform remote writes use a single toggle:
mode: "plan" | "apply"
Behavior:
mode="plan"(default): no remote mutations occur. The tool returns what it would do.mode="apply": the tool performs the remote write.
Long-running / interactive CLI workflows
Some workflows are interactive or start a dev server. The MCP server exposes instruction-only tools that return exact terminal commands instead of spawning processes:
tapcart_dev_instructions
MCP tool index
Project & auth
tapcart_project_info(read)tapcart_project_create(local-write; best-effort remote read for dependency defaults)tapcart_auth_status(read)tapcart_auth_login_instructions(instructions)tapcart_auth_logout(local-write)
Local development helpers
tapcart_blocks_createLocal(local-write)tapcart_components_createLocal(local-write)tapcart_types_sync(local-write)tapcart_log_show(read)tapcart_lint(read; iffix=truethen local-write gated bymode)tapcart_dev_instructions(instructions)
Blocks
tapcart_blocks_listRemote(read)tapcart_blocks_pull(read + local-write)tapcart_blocks_push(remote-write gated bymode)tapcart_block_versions_list(read)tapcart_block_versions_set(remote-write gated bymode)
Components
tapcart_components_listRemote(read)tapcart_components_pull(read + local-write)tapcart_components_push(remote-write gated bymode)tapcart_component_versions_list(read)tapcart_component_versions_set(remote-write gated bymode)
Dependencies
tapcart_dependencies_listLocal(read)tapcart_dependencies_addLocal(local-write)tapcart_dependencies_removeLocal(local-write)tapcart_dependencies_pullRemote(read + local-write)tapcart_dependencies_pushRemote(remote-write gated bymode)
Layouts
tapcart_layout_new(local-write)tapcart_layout_add(local-write)tapcart_layout_remove(local-write)tapcart_layout_reorder(local-write)tapcart_layout_set(local-write)tapcart_layout_tab_add(local-write)tapcart_layout_tab_remove(local-write)tapcart_layout_tab_rename(local-write)tapcart_layout_list(read)tapcart_layout_show(read)tapcart_layout_validate(read)
Docs & introspection
tapcart_docs_search(read)tapcart_mcp_capabilities(read)
MCP recipes
Recipe: first-time setup
tapcart_project_info(confirmtapcartEnv,apiBaseUrl,appId)If not authenticated:
tapcart_auth_login_instructionsthen run the command in a terminalPull your blocks locally:
tapcart_blocks_pullwithall=true
Recipe: edit a block and publish safely
- Pull the latest version of a block:
tapcart_blocks_pullwithlabels=["MyBlock"]
Edit local files under
./blocks/<block>/(e.g.code.jsx)Plan a push:
tapcart_blocks_pushwithlabels=["MyBlock"]andmode="plan"
- Apply the push:
tapcart_blocks_pushwithlabels=["MyBlock"]andmode="apply"
- (Optional) Set a specific version live:
tapcart_block_versions_setwithlabel="MyBlock",version=<n>,mode="plan"thenmode="apply"
Recipe: update dependencies
- Add locally:
tapcart_dependencies_addLocalwithname,version
- Plan remote push:
tapcart_dependencies_pushRemotewithmode="plan"
- Apply remote push:
tapcart_dependencies_pushRemotewithmode="apply"
Importing Software Dependencies
You can import software dependencies into your block. This is done by adding the
dependencies to your project via tapcart dependency add command. For example:
tapcart dependency add lodash 4.17.21This will add the lodash library to your app's dependencies. You must specify
which blocks you want to add the dependency to. This is done by editing the
block's config.json file.
{
"dependencies": ["lodash"]
}Then, you can import the dependency in your block's code.jsx file:
import * as _ from 'lodash';Note: The Tapcart ecosystem does not support React component libraries like
@mui/material. For UI components, you should use the Tapcart component
library.
Pushing Dependencies
You must push your dependencies to your application configuration before they will work in the dashboard or the mobile app. You can do this by running:
tapcart dependency pushThis will push the dependencies to your application configuration.
- Push the block to your block bank
When you're satisfied with your changes, push the block to your block bank. Then head over to the dashboard where you'll be able to see it.
tapcart block push HelloWorld
tapcart block push HelloWorld -m "Fix CTA spacing" # optional custom push message
tapcart block push --all # push every local blockblock push also runs a non-blocking ESLint pass over the block(s) first and
prints any warnings/errors — it never blocks the push.
Pushing your block by default does not make it live. You'll need set the version
as live after pushing, or use the --live flag when pushing.
tapcart block versions list HelloWorld
✔ Block versions:
┌─────────┬───────────────┬───────────────────┬──────────────────────────┬──────────────┬──────────────┐
│ Version │ Date Modified │ Message │ ID │ LocalVersion │ RemoteVersion│
├─────────┼───────────────┼───────────────────┼──────────────────────────┼──────────────┼──────────────┤
│ 1 │ 6/1/2026, ... │ Tapcart CLI push │ 679d443708d1e5fa9938651a │ active │ - │
└─────────┴───────────────┴───────────────────┴──────────────────────────┴──────────────┴──────────────┘The versions table is interactive — use ↑/↓ to scroll, PgUp/PgDn to jump a page,
q to quit.
tapcart block versions set HelloWorld -v 1
✔ Block version set to 1Or, to do it all in one step:
tapcart block push HelloWorld --live
# non-interactive/CI/agent use — skip the confirmation prompt:
tapcart block push HelloWorld --live --yes[!WARNING] Running
push --livewill create a new version of the block and set it as live. If you push without the--liveflag, it is recommended to set the version as live viablock versionscommand to avoid creating duplicate versions.
Working with Global Components
Global components are reusable React components that can be shared across multiple blocks. The Tapcart CLI provides commands to create, develop, push, and pull global components.
Creating a Component
Create a new global component:
tapcart component create ProductCardThis will create a new component in the components directory with the
following structure:
components/ProductCard/
|--- code.jsx
|--- config.json
|--- manifest.json
|--- manifestConfig.jsonDeveloping a Component
Run a local development server for your component:
tapcart dev component ProductCardThis will start a development server where you can preview and test your component with hot-reloading.
Pushing Components
Push your component to the Tapcart dashboard:
tapcart component push ProductCardYou can also push multiple components at once:
tapcart component push ProductCard ButtonOr push all components:
tapcart component push --allcomponent push supports the same --live/-l and --message/-m flags as
block push (see above).
Pulling Components
Pull down the latest version of a component:
tapcart component pull ProductCardPull a specific version of a component:
tapcart component pull ProductCard --version 2Pull multiple components:
tapcart component pull ProductCard ButtonOr pull all components:
tapcart component pull --allManaging Component Versions
The component versions command has the same structure as the block versions command (though its table has no Date Modified/Message columns — those are block-only):
# List all versions of a component
tapcart component versions list MyComponent# Set a specific version as the active version on the server
tapcart component versions set MyComponent -v 2# Set a specific version as the active version locally without changing the server
tapcart component pull MyComponent --version 1Note that the version index is 1-based, so set MyComponent 1 sets the first
version as active.
When listing component versions, you'll see both the local version (marked as "active" in the LocalVersion column) and the remote version (marked as "live" in the RemoteVersion column).
Layouts
Layouts are a collection of blocks that create a page - for example your home page. You can preview a layout stored on the server with:
tapcart dev layout [target] # target = layout ID or screen type; omit to pick interactively
tapcart dev layout home # e.g. preview the home-screen layoutBy default, the dev server renders the layout with the server version of every
block. To preview it with local block versions instead, use the block toggles
in the dev server's browser UI (this replaced the old --block/--all
CLI flags).
Mock layouts locally
Compose and preview layouts entirely from your local block and component folders without using the dashboard. Define layouts as JSON files and preview them with the dev server.
Layout files
Layout files are stored in .tapcart/layouts/<name>.json — one file per layout. Each layout is a JSON object that references blocks and components by folder name and arranges them into a page:
{
"contentLayout": "list",
"blocks": [
{ "use": "ButtonBlock", "as": "cta", "config": { "text": "Shop now" } },
{ "use": "ProductGrid" }
]
}For tabbed layouts:
{
"contentLayout": "tabbed-list",
"tabs": [
{
"title": "New",
"blocks": [
{ "use": "ProductGrid" }
]
}
]
}Each block entry supports:
use— the folder name of a local block or component (non-empty string)config(optional) — a partial manifest config object merged over the block's defaultsas(optional) — a stable handle for addressing repeated blocks (non-empty string)
contentLayout must be exactly "list" or "tabbed-list" — "list" layouts
require blocks, "tabbed-list" layouts require tabs (the two are mutually
exclusive). All layout objects are validated strictly — unrecognized keys will
fail tapcart layout validate.
Layout commands
tapcart layout new <name> [--tabbed]
tapcart layout add <use> [--layout <name>] [--tab <title>] [--pos <i>] [--as <handle>] [--config '<json>']
tapcart layout set <name> <handle> <key=value...>
tapcart layout reorder <name> <from> <to>
tapcart layout remove <name> <handle>
tapcart layout tab add|remove|rename <name> ...
tapcart layout list
tapcart layout show <name>
tapcart layout validate [name]Machine-readable output and validation
All commands accept --json to output results in a parseable format. This is useful for scripts and tools that need to manipulate layouts programmatically.
The tapcart layout validate command checks a layout against the schema and confirms that every use reference resolves to a local block or component folder. A $schema reference is written into each layout file for editor autocomplete.
Preview
Once a layout file exists at .tapcart/layouts/<name>.json, preview it with:
tapcart dev layout <name>This renders the layout through the same pipeline as a layout stored on the server.
Linting
Run ESLint over your blocks and components:
tapcart lint my-hero-banner # lint one target (block or component) by folder name
tapcart lint my-hero-banner ProductCard # lint a block and a component together
tapcart lint my-hero-banner --fix # auto-fix
tapcart lint --all # lint every block and component
tapcart lint # no targets/flags: pick interactivelyPositional targets are resolved by folder name — the CLI checks ./blocks/<name>
then ./components/<name>, so you don't need to say which kind it is.
--blocks/-b and --components/-c also still work, and each accept multiple
folder names (e.g. tapcart lint -b my-hero-banner -c ProductCard). block push
and component push also run a non-blocking lint pass automatically.
Viewing Logs
Show recent Tapcart CLI logs (~/.tapcart/cli.log) — useful for debugging:
tapcart log show # last 100 lines
tapcart log show -n 20 # last 20 linesGlobal options
These flags apply to every command:
--verbose, -V— run with verbose logging--quiet, -q— run with no logging--json— emit machine-readable JSON to stdout and suppress all other output (for scripts and agents)--yes, -y— skip interactive confirmation prompts, e.g. the--livepush confirmation (required for non-interactive/CI/agent use)
Help
Open the help menu for any command with the -h (or --help) option.
# Examples
tapcart -h
tapcart block -h
tapcart component -h
tapcart layout -hCLI Version
See your version of the Tapcart CLI.
# Example
tapcart -v # shorthand for --versionShell completion
tapcart completion prints a tab-completion script for your shell. It completes
command names (block, component, push, …) and flags (--all, --live,
--json, …). Completion requires the globally-installed tapcart binary.
Zsh — append to ~/.zshrc:
tapcart completion >> ~/.zshrc
exec zsh # reload (or open a new terminal)If zsh reports command not found: compdef, initialize completions once at the
top of ~/.zshrc (before the line above):
autoload -Uz compinit && compinitBash — append to ~/.bashrc (or ~/.bash_profile on macOS):
tapcart completion >> ~/.bashrc
source ~/.bashrc # reload (or open a new terminal)To try it in the current session without editing your rc file:
source <(tapcart completion)Note: completion covers commands and flags, not dynamic values — e.g. it does not suggest your local block/component folder names.
