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

@tapcart/tapcart-cli

v3.0.0

Published

The Tapcart CLI is a command-line interface for managing and developing blocks.

Downloads

1,106

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-cli

Get started developing Blocks

  1. 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 editor

There'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.

  1. 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 login

This 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.

  1. (Optional) Pull down existing blocks

Now pull down the blocks

tapcart block pull --all

You'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.json
  • code.jsx: This is the React component code for the block
  • config.json: This holds high-level metadata about the block, such as its label and tags. 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.
  1. Create a new block
tapcart block create HelloWorld
  1. Run the new block (or an existing block that was pulled down)
tapcart dev block HelloWorld

This 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-data route that reads mockData.json from 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-data once per session via the useMockData() 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-root mockData.json (matching mockData.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- write mockData.json yourself; 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 sync

Preview URL Parameters

The dev server's browser UI (http://localhost:4995 by default) reads a number of query parameters for previewing specific states without touching local files. Most are also mirrored by toolbar controls that set them for you.

| Parameter | Effect | | --- | --- | | ?config=<preset> | Loads a named config preset from <block>/__tests__/<name>.json instead of the block's default manifestConfig.json. | | ?fullDevice=true | Lets the device frame fill the available canvas height instead of capping it at the selected device's height. | | ?state=<filled\|empty\|signed-out> | Selects the manifest tab a state-aware block itself declares (filledTab/emptyTab/signedOutTab). Only shown for blocks that expose those tabs, and only changes which variant that block renders. |

[!NOTE] ?state=signed-out and a null customer are two different mechanisms, not interchangeable. Setting "customer": null in the project's root mockData.json changes the bridge variables themselves — each key there shallow-overrides the live value — so there genuinely is no customer, which affects any block that reads customer, regardless of manifest tabs. Use ?state=signed-out for blocks with a signedOutTab; use mockData.json's customer: null for everything else that needs a signed-out shopper.

/live-block (the route behind the "show live preview" toggle) additionally accepts the parameters below. These are honored on direct requests to the dev server (e.g. curl, a browser tab pointed straight at /live-block?...) — the browser UI's "show live preview" toggle does not forward them; it only ever sends label and mode.

| Parameter | Effect | | --- | --- | | ?env=<local\|staging\|production> | Fetches the live block/component from a different environment. Defaults to the CLI's configured launch env. | | ?appId=<id> | Fetches the live block/component for a different App ID. Defaults to the project's configured App ID. | | ?versionIndex=<n> | 0-based block version to fetch. Defaults to the latest published version. |

MCP (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.json as 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 mcp

Notes:

  • 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 projectPath when 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=production

Safety 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; if fix=true then local-write gated by mode)
  • tapcart_dev_instructions (instructions)

Blocks

  • tapcart_blocks_listRemote (read)
  • tapcart_blocks_pull (read + local-write)
  • tapcart_blocks_push (remote-write gated by mode)
  • tapcart_block_versions_list (read)
  • tapcart_block_versions_set (remote-write gated by mode)

Components

  • tapcart_components_listRemote (read)
  • tapcart_components_pull (read + local-write)
  • tapcart_components_push (remote-write gated by mode)
  • tapcart_component_versions_list (read)
  • tapcart_component_versions_set (remote-write gated by mode)

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 by mode)

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

  1. tapcart_project_info (confirm tapcartEnv, apiBaseUrl, appId)

  2. If not authenticated: tapcart_auth_login_instructions then run the command in a terminal

  3. Pull your blocks locally:

  • tapcart_blocks_pull with all=true

Recipe: edit a block and publish safely

  1. Pull the latest version of a block:
  • tapcart_blocks_pull with labels=["MyBlock"]
  1. Edit local files under ./blocks/<block>/ (e.g. code.jsx)

  2. Plan a push:

  • tapcart_blocks_push with labels=["MyBlock"] and mode="plan"
  1. Apply the push:
  • tapcart_blocks_push with labels=["MyBlock"] and mode="apply"
  1. (Optional) Set a specific version live:
  • tapcart_block_versions_set with label="MyBlock", version=<n>, mode="plan" then mode="apply"

Recipe: update dependencies

  1. Add locally:
  • tapcart_dependencies_addLocal with name, version
  1. Plan remote push:
  • tapcart_dependencies_pushRemote with mode="plan"
  1. Apply remote push:
  • tapcart_dependencies_pushRemote with mode="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.21

This 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 push

This will push the dependencies to your application configuration.

  1. 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 block

block 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 1

Or, 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 --live will create a new version of the block and set it as live. If you push without the --live flag, it is recommended to set the version as live via block versions command 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 ProductCard

This will create a new component in the components directory with the following structure:

components/ProductCard/
 |--- code.jsx
 |--- config.json
 |--- manifest.json

A manifestConfig.json is intentionally NOT scaffolded: the publish API treats a present manifestConfig as the complete stored config ({} clears all overrides), so push omits the field until you create the file yourself (or until tapcart component pull writes one, which it only does when the component actually has stored overrides).

manifestConfig.json is also the only source of those semantics — a manifestConfig or replaceManifestConfig key written into config.json is ignored and stripped from the payload.

Upgrading from CLI v2.3.1 or earlier: those versions DID scaffold an empty manifestConfig.json containing just {}. Pushing that leftover file now replaces the component's stored config, clearing every saved override. Review your existing components and delete any manifestConfig.json whose contents are only {} unless you deliberately authored it to clear the config. Every component push warns (and lists the components in its --json warnings array) when it is about to send an empty {}; --live additionally names them in its confirmation prompt. Re-running tapcart component pull also cleans them up: it deletes a local manifestConfig.json whenever the server has no stored overrides.

Server requirement: a push that carries a manifestConfig.json sends replaceManifestConfig, which requires the components API from tapcartinc/tapcart-microservices#4317. Against an API server that predates it, such a push is rejected with a 400. Components with no manifestConfig.json are unaffected — they omit both fields and keep the server's legacy merge behaviour.

Developing a Component

Run a local development server for your component:

tapcart dev component ProductCard

This 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 ProductCard

You can also push multiple components at once:

tapcart component push ProductCard Button

Or push all components:

tapcart component push --all

component 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 ProductCard

Pull a specific version of a component:

tapcart component pull ProductCard --version 2

Pull multiple components:

tapcart component pull ProductCard Button

Or pull all components:

tapcart component pull --all

Pull mirrors the server, including the absence of configuration: when a component has no stored manifest-config overrides, pull writes no manifestConfig.json and deletes any local one, logging what it removed. That keeps the next component push omitting the manifestConfig field entirely (stored config left untouched) rather than sending an empty {} (clear every override).

Managing 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 1

Note 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 layout

By 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 defaults
  • as (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 interactively

Positional 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 lines

Global 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 --live push confirmation (required for non-interactive/CI/agent use)
  • --skip-update-check — don't check npm for a newer CLI version

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 -h

CLI Version

See your version of the Tapcart CLI.

# Example
tapcart -v # shorthand for --version

Staying up to date

The CLI checks npm for a newer version and offers to update itself. When a newer version exists it asks once per version — decline and it won't ask again until a newer one ships. Accepting installs it and re-runs your original command on the new version.

Only tapcart update installs without asking. --yes skips confirmation prompts; it deliberately does not authorize replacing your CLI mid-command.

This arrived in v3.0.0. Versions 2.x and earlier have no update check at all, so they can't be moved forward from here — if one of them ever has to be retired, it will be turned away at the API instead.

tapcart update          # update to the latest published version
tapcart update --check  # report what's available, install nothing

The check adds a single ~41-byte request, capped at 1.5 seconds, and its answer is cached for five minutes. It always fails open: if npm is unreachable, slow, or blocked by a proxy, your command runs anyway.

It updates the CLI in place only when it can do so safely — a global install via npm, pnpm, yarn, Volta, or Bun. When the CLI is a project dependency, a npx run, a Homebrew formula, or a linked source checkout, it never prompts: it states what to run instead, once per version, and changes nothing.

To turn it off:

  • --skip-update-check on any command
  • TAPCART_SKIP_UPDATE_CHECK=1 in the environment
  • automatically whenever CI is set — builds install the version they pinned, and should never move underneath a job

Two more environment variables, both rarely needed:

  • TAPCART_REGISTRY — check a different registry (https, or http://localhost for testing). Anything else is ignored and npmjs is used. Note this is not read from npm_config_registry: that value comes from whichever .npmrc is nearest, and this host decides which CLI version you're told to run.
  • TAPCART_ALLOW_UNSUPPORTED_VERSION=1 — run anyway when your version is outside the supported range, with a warning. For bisecting old versions.

After an update, the first run prints a one-line note about what changed. Set it for a release with the tapcart.releaseNote field in package.json:

{
    "tapcart": {
        "releaseNote": "Fixes republishing an archived GlobalComponent. Re-pull your GlobalComponents to sync metadata."
    }
}

Keep it to what the reader has to do — it interrupts everyone exactly once, so "re-pull your components" earns that and "various fixes" does not.

Shell 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 && compinit

Bash — 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.