vibemonetize (CLI)
npx vibemonetize wraps an existing Next.js (App Router) or Vite + React app
in VibeMonetize in a few commands, without ever requiring the dashboard: wire
the SDK into your code, get a developer account and API keys from the
terminal, and provision an App with its Features/Meters/Plans — all from one
CLI.
Zero runtime dependencies. init never touches the network; signup,
app create, bundle create, grant, and doctor's remote checks do.
Install & run
npx vibemonetize init
Run it from the root of your project (next to package.json). Pass a
directory to target a different project: npx vibemonetize init ./apps/my-app.
No developer account yet? Get one from the terminal:
npx vibemonetize signup --email you@example.com # emails a 6-digit code
npx vibemonetize signup --email you@example.com --code 123456
Then provision an app:
npx vibemonetize app create --secret-key sk_... \
--feature pro --meter exports=20 --plan "Pro" --price 900
vibemonetize init
Detects your framework and wires the SDK in. Safe to run more than once — every step only fills in what's missing; it never duplicates or clobbers hand edits.
Framework detection
- Next.js App Router: an
app/orsrc/appdirectory with a rootlayout.tsx/.jsx/.ts/.jsfile, plus anextdependency. - Vite + React: a
vite.config.*file, areactdependency, and asrc/main.tsx-style entry point. - Anything else (no
package.json, a Next.js Pages Router project, a non-React Vite project) is refused politely with a specific, actionable reason —initnever guesses.
What it writes
- Adds
@vibemonetize/reactand@vibemonetize/servertopackage.json. - Wraps your app root in
<MonetizeProvider>:- Next.js — generates
app/providers.tsx(a"use client"boundary) and renders it fromapp/layout.tsx. An existingproviders.tsxhas its{children}wrapped in place rather than being replaced. - Vite — wraps whatever is passed to
.render(...)insrc/main.tsx.
- Next.js — generates
- Writes
.env.local(gitignored placeholders) and.env.example(documents the required shape) with the client vars (NEXT_PUBLIC_/VITE_-prefixedVIBEMONETIZE_APP_ID,_API_URL,_PUBLISHABLE_KEY,_TEST_PUBLISHABLE_KEY) and, for Next.js, the unprefixed server vars@vibemonetize/serverreads by default (VIBEMONETIZE_SECRET_KEY,VIBEMONETIZE_TEST_SECRET_KEY). See "Env vars" below for the full list. - If no Tailwind is detected, adds
import "@vibemonetize/react/styles.css";so components render styled with zero build step. - Drops a starter
components/VibemonetizeExample.tsxusing<Paywall>,<UsageBadge>, and<CheckoutButton>— delete it once you've built your own paywall. - Adds
@vibemonetize/seoand drops an SEO starter (for Next.js:app/sitemap.ts/app/robots.ts; for Vite: staticpublic/sitemap.xml/public/robots.txt). - Writes/regenerates
MONETIZE.mddescribing the integration — this one file is intentionally always regenerated (everything else above is additive-only).
Flags
--readme-badge— append a "Monetized with VibeMonetize" line toREADME.md, only if one already exists. Opt-in; omit it andREADME.mdis never touched.
Idempotency: re-running init against an already-wired project only
fills in whatever's still missing. It never spawns a package manager or makes
a network call — it edits files on disk and tells you the one install command
to run afterward.
vibemonetize signup
Gets a developer account and API keys from the terminal, no dashboard needed. Two invocations, no interactive prompts:
npx vibemonetize signup --email you@example.com # sends a 6-digit code by email
npx vibemonetize signup --email you@example.com --code 123456 # verifies + mints keys
Mints a test-mode key pair (sk_test_/pk_test_) by default, so the
first thing you can do with it is exercise the whole paywall → checkout →
entitlement loop with zero real charges. Writes the keys into the target
directory's .env.local (or prints them if no Next.js/Vite project is
detected there) — never echoed to the terminal once written to disk.
Flags
--email <email>— required.--code <code>— the 6-digit code from the signup email. Omit on the first invocation.--api-url <url>— Monetization API base URL. Default:VIBEMONETIZE_API_URLenv var, then an existing*VIBEMONETIZE_API_URLvalue already in.env.local/.env.example, thenhttps://api.vibemonetize.dev.
vibemonetize app create
Given a developer secret key, provisions an App (and, optionally,
Features/Meters/one-or-more Plans/a publishable key) via the Monetization API
and writes the resulting ids straight into .env.local/.env.example — no
hand-copying ids out of the dashboard. Safe to run more than once: a rerun
reuses whatever's already provisioned instead of duplicating it.
Flags
--name <name>— app name. Default: the target'spackage.json"name".--url <url>— where this app is/will be deployed (a bare domain or a full URL — normalized to a bare domain either way). Only applied when this run actually creates the app (never overwrites an existing app's domain on reuse). If omitted: inferred frompackage.json's"homepage"field orvercel.json's"alias"when confident; in an interactive terminal you're prompted once (pre-filled with the inferred value, enter to skip); in a non-interactive run (CI, a coding agent) the inferred value is used silently, or skipped if nothing was found — this flag never blocks.--template <name>— provision a recommended pricing pack instead of spelling out--feature/--meter/--planflags (mutually exclusive with them; edit prices/caps in the dashboard afterward):saas— Free (20 actions/mo) + Pro $9/mo.ai-credits— 10 free credits + $5/50 and $15/200 stacking credit packs.daily-free— Free (3 generations/day, resets daily) + Pro $9/mo.
--api-url <url>— as insignup.--secret-key <key>— developer secret key (sk_...). Default:VIBEMONETIZE_SECRET_KEYenv var, then a matching line in.env.local. Never printed.--feature <slug>— create a Feature with this slug. Repeatable. Granted to every paid (--price> 0)--planin this run — never to a $0 plan unless--grant-to-free-plansis also passed. Warns loudly if a feature ends up granted to no plan, or skipped on a $0 plan.--meter <slug>[=<cap>]— create a Meter, optionally capped. The inline cap only applies when exactly one--planis given this run; use--capto scope a meter's cap to a specific plan when there's more than one. Repeatable.--period <period>— reset period for the most recent--meter:month|day|lifetime|credit. Default:month.--plan <name>— create a Plan. Repeatable — each--planstarts a new plan;--slug/--price/--interval/--capapply to the most recently seen--plan.--slug <slug>— explicit slug for the most recent--plan. Default: slugifiedname.--price <cents>— price in cents for the most recent--plan. Default:0(free).--interval <interval>— interval for the most recent--plan:month|year|one_time|lifetime|credits. Default:month. See "Credit packs" below for whatcreditsactually changes.--cap <meterSlug>=<cap>— cap a--meter's usage for the most recent--planspecifically (e.g. a free plan capped, a pro plan uncapped). Required instead of the inline--meter <slug>=<cap>form whenever more than one--planis given. Repeatable.--grant-to-free-plans— also grant this run's--features to $0 plans. Off by default, so a free tier never silently gets a paid feature.--no-store— skip listing this app in the public VibeMonetize store. Default: listed (opt out anytime — this flag, or unlist later in the dashboard).--rotate-keys— force-mint a new publishable key pair (and overwrite both env vars) even if one already exists. Off by default: a run that finds an existingpk_...in either the live or test var reuses it as-is.
Credit packs (--interval credits): a --plan's --cap <meterSlug>=<cap> is written with a credit reset period instead of the
usual monthly one whenever that plan's own --interval is credits.
Entitlement resolution takes the maximum cap across a meter's month/day/
lifetime limits, but sums across its credit limits — so a credit-period cap
is what makes a purchased pack an additive top-up (it stacks on top of a
subscription's cap, and two packs sum with each other) instead of a second
ceiling that just gets maxed away. Every other --interval is unaffected.
Example — free/pro/yearly in one run:
vibemonetize app create --secret-key sk_... --feature pro \
--meter exports \
--plan Free --cap exports=5 \
--plan "Pro Monthly" --slug pro-monthly --price 900 --interval month \
--plan "Pro Yearly" --slug pro-yearly --price 9000 --interval year
vibemonetize bundle create
Provisions a developer-scoped Bundle (a Plan container with cross-app
grants) and, optionally, one Bundle Plan spanning two or more of your apps'
Features/Meters. Idempotent like app create: a rerun with the same
--name/--plan reuses what already exists. Works with an sk_... key; no
directory scaffolding (a bundle isn't tied to one app's env files, so
nothing is written to disk).
Flags
--name <name>— bundle name. Required.--slug <slug>— explicit bundle slug. Default: slugifiedname.--api-url <url>/--secret-key <key>— as inapp create.--plan <name>— create one Plan on this bundle. Omit to create the bundle only, with no plan yet.--plan-slug <slug>— explicit slug for--plan. Default: slugifiedname.--price <cents>— price in cents for--plan. Default:0.--interval <interval>— interval for--plan:month|year|one_time|lifetime|credits.--grant <appId>:<featureSlug>— grant this app's feature in the bundle's plan. Repeatable — a plan spanning 2+ distinct app ids is what makes it an actual cross-app bundle.--cap <appId>:<meterSlug>=<cap>— cap this app's meter in the bundle's plan. Repeatable.
Example — a bundle plan spanning two apps' "pro" feature:
vibemonetize bundle create --secret-key sk_... --name "All Apps" \
--plan "All Access" --price 1900 --interval month \
--grant <appOneId>:pro --grant <appTwoId>:pro
vibemonetize grant
Comps a plan to an end user by email — the fast way to prove a locked
feature unlocks, with no Stripe checkout or browser needed. Creates a comp
membership in your key's mode; with the default sk_test_ key it's invisible
to live traffic. Sign in as that email in your app and watch the gate open.
Flags
--email <email>— who gets the plan. Required.--plan <planSlug>— plan slug to grant (e.g."pro"). Required.--app-id <id>— app id. Default: the value in.env.local.--expires-days <n>— time-box the comp tondays. Default: never expires.--api-url <url>/--secret-key <key>— as above.
vibemonetize doctor
Verifies the integration end to end and prints the exact fix for anything
broken. Local checks (framework detection, SDK dependencies,
<MonetizeProvider> wiring, env vars, no secret key sitting in a
client-bundled var, Tailwind/styles coverage) are always offline. Remote
checks (API reachability, key validity, that a plan exists to sell, and how
far the checkout funnel has actually fired) run only when an API URL and
keys are configured, and degrade to skipped — never failed — when
they're not.
npx vibemonetize doctor # human-readable report
npx vibemonetize doctor --json # machine-readable, for agents/CI
Flags
--api-url <url>— Monetization API base URL. Default:VIBEMONETIZE_API_URLenv var, then an existing value in.env.local.--secret-key <key>— developer secret key. Default:VIBEMONETIZE_SECRET_KEY/VIBEMONETIZE_TEST_SECRET_KEYenv var, then.env.local. Never printed.--json— machine-readable output.
Exits 0 when nothing blocking was found (warnings are still allowed),
1 when any check failed — scriptable as a post-integration gate in CI or
by a coding agent.
Env vars
| Var | Where | What |
|---|---|---|
VIBEMONETIZE_API_URL |
signup, app create, bundle create, grant, doctor |
Monetization API base URL, checked before .env.local. Falls back to https://api.vibemonetize.dev if nothing else is set. |
VIBEMONETIZE_SECRET_KEY |
app create, bundle create, grant, doctor |
Developer secret key (sk_...), checked before .env.local. Never printed. |
VIBEMONETIZE_INSTALL_CHANNEL |
any command | Attribution tag on signup/init/app create events (assistant | cli | docs) — same as the --channel flag; ignored (with a warning, never a crash) if unset or invalid. |
init/app create also write the client-side vars every VibeMonetize SDK
reads — NEXT_PUBLIC_/VITE_-prefixed VIBEMONETIZE_APP_ID, _API_URL,
_PUBLISHABLE_KEY, _TEST_PUBLISHABLE_KEY — plus, for Next.js, the
unprefixed server-side VIBEMONETIZE_APP_ID, _API_URL, _SECRET_KEY,
_TEST_SECRET_KEY that @vibemonetize/server reads by default. See the
"init" section above for the full list with descriptions.
Options
-h,--help— show the CLI's help output.-v,--version— show the CLI version.--channel <c>— attribution tag on signup/init/app create (assistant|cli|docs; same as theVIBEMONETIZE_INSTALL_CHANNELenv var); ignored if unset or invalid.