CLI Setup
The LaunchMyStore CLI (lms) helps you create, develop, test, and deploy apps,
extensions, and functions from the command line. The CLI is a Node 18+ ESM
package that talks to the LaunchMyStore API and signs webhooks locally for
end-to-end development.
@launchmystore/cli@2.0.3 is live. Functions compile to WASM on
your machine using Bytecode Alliance Javy;
the server only validates that uploads are Javy dynamic-mode modules — it
never runs your source through a compiler. lms extension push -t now
accepts the developer-friendly type names emitted by lms extension generate
(theme_block, function_payment, etc.) and maps them to the canonical
upload types automatically.Installation
Requires Node.js 18 or higher. To build functions you’ll also need Javy v3+ on yourPATH
(or pointed to by the JAVY_BIN_PATH environment variable).
The flag is
--cli-version (not --version) so it doesn’t collide with
the subcommand-level --version <semver> flag used by lms app version
and lms app deploy.Authentication
The CLI authenticates with email and password and stores a refreshable credential bundle in~/.lms/credentials.json (override the directory with the
LMS_CONFIG_DIR environment variable).
Project Configuration
After you scaffold an app, the CLI walks up from your current working directory looking for a.lmsrc.json file. This file binds the local project to a
specific app in the developer dashboard so subsequent commands know which app
they’re operating on.
.lmsrc.json
--app flag to
target a specific app explicitly. Without it, they fall back to the appId in
the nearest .lmsrc.json.
Quickstart
1
Sign in
2
Create an app
Pick a template (
node, react, or extension-only). The CLI registers
the app, scaffolds the project, and writes .lmsrc.json + .env.3
Install dependencies
4
Run the dev server with a tunnel
extensions/, and PATCHes the app’s redirect URLs to point at the tunnel.Templates
lms app create can scaffold one of three starter templates. Pass
--no-template to skip scaffolding and only register the app remotely.
Commands Reference
Auth
App
App Versions
Function
Extension
lms extension generate is a local-only scaffolder. Functions are written to
functions/<handle>/ and all other extension types to extensions/<handle>/.
Webhook
Billing
Versioning
Use theapp version subgroup to ship releases. The CLI separates
create (uploads the artifact + metadata) from publish (makes it available to
merchants), so you can stage a build and review it before promoting.
lms app deploy --version 1.2.0.
For the full lifecycle — auto-update channels, deprecation policy, rollback —
see App Versioning.
Local Function Compilation
Functions ship as Javy dynamic-mode WASM modules. Your JavaScript is compiled on your machine into a tiny stub (typically 1–4 KB) that links against a shared QuickJS runtime (“provider”) at execution time — so each compiled function only carries your code, not a copy of the runtime. The server never runs your source through a compiler. It receives a pre-built.wasm, validates the import section to confirm it’s a Javy
dynamic-mode build, then stores it.
Build a function
If
javy isn’t on your PATH, point at it explicitly:
Test against the sandbox
lms function test either compiles locally first (-f) or uploads a
pre-built artifact (--wasm), then runs it against the hosted sandbox
without persisting anything. The fastest way to iterate.
discount, shipping_rate, payment_customization,
order_validation, cart_transform, delivery_customization.
Deploy to your app
Function source contract
Export arun (or main) function that takes the input object and returns
the output object — the CLI wraps your source with the stdin/stdout bridge
expected by Javy:
module.exports = fn, function main(input) {}, or
exports.default = fn for compatibility with different bundler outputs.
Size limits
A typical discount function compiles to ~3 KB. If you’re approaching the
256 KB cap you’re probably bundling unnecessary dependencies — strip them
out rather than asking for a higher cap.
Local Webhook Testing
The CLI can simulate the production webhook dispatcher locally. It generates a realistic sample payload for the topic, signs it with HMAC-SHA256 using your client secret, and POSTs it to your local URL with the same headers your production server will receive:X-LMS-Topic, X-LMS-Webhook-Id,
X-LMS-Delivery-Attempt, X-LMS-Hmac-SHA256.
GDPR compliance topics (
customers/data_request, customers/redact,
shop/redact) are delivered by the platform but are not registerable
via the webhook API — you don’t subscribe to them explicitly.Configuration
The CLI reads project config from.lmsrc.json and credentials from
~/.lms/credentials.json. You can override the credentials directory globally
with LMS_CONFIG_DIR — useful for keeping work and personal accounts separate,
or for sandboxing CI.
Environment Variables
Troubleshooting
'lms' command not found
'lms' command not found
Make sure your npm global On macOS with Homebrew Node, this is usually
bin directory is on your PATH:/opt/homebrew/bin. On
Windows, it’s typically %APPDATA%\npm.Authentication expired or invalid
Authentication expired or invalid
Long-lived sessions can be invalidated by a password change or admin
revoke. Re-authenticate:
`lms extension push --type theme_block` rejected as invalid type
`lms extension push --type theme_block` rejected as invalid type
Fixed in
@launchmystore/cli@2.0.3 — the developer-friendly type names
from lms extension generate (theme_block, storefront_snippet,
checkout_ui, post_purchase, and all six function_* variants) now
map automatically to the canonical upload types (app_block,
checkout_extension, app_function). Upgrade with
npm install -g @launchmystore/cli@latest and verify with
lms --cli-version.Tunnel won't start in 'lms app dev'
Tunnel won't start in 'lms app dev'
lms app dev uses the cloudflared package. Make sure port 3000 is free
(or pass --port), and that no firewall is blocking outbound connections
to Cloudflare. To run without a tunnel — for example when your dev server
is already publicly reachable — pass --no-tunnel and --no-update-urls.Commands can't find my app
Commands can't find my app
Most commands resolve the active app from
.lmsrc.json walked up from
cwd. If you’re outside the project directory, pass --app <handle> (or
--app <appId>) explicitly.Javy compiler not found
Javy compiler not found
lms function build calls out to the javy binary. Install it from
the Javy releases page
and either put it on your PATH or set JAVY_BIN_PATH to its absolute
location. Verify with:WASM rejected as 'not a Javy dynamic-mode module'
WASM rejected as 'not a Javy dynamic-mode module'
The upload endpoint checks the WASM import section for the
javy_quickjs_provider marker. Static-mode builds (which embed the
runtime instead of linking against the shared provider) are rejected
because they exceed the size cap by orders of magnitude. Always
compile with javy compile -d — the lms function build command
does this for you automatically.Webhook signature mismatches my server
Webhook signature mismatches my server
lms webhook trigger uses HMAC-SHA256 with the client secret as the key,
over the raw JSON body, and sends the result in the X-LMS-Hmac-SHA256
header (base64-encoded). Verify your server is hashing the raw request
body, not a re-serialized version, and that you’re using the same client
secret the CLI is loading from --secret or LMS_CLIENT_SECRET.Use with Claude Code
If you use Claude Code, install the LaunchMyStore Claude Skill to let Claude route plain-English requests (“build a discount function”, “list my orders”, “add a hero section”) to the right CLI command, MCP tool, App Bridge action, or Aqua snippet./launchmystore I want to build my first app.
Source: github.com/LaunchMyStore/skill
Next Steps
Build Your First App
A complete walkthrough using the
node templateApp Versioning
Release, publish, deprecate, and roll back versions
Functions Overview
Build, test, and deploy custom function logic with the CLI
App Bridge
Embed your app in the LaunchMyStore admin