create-convex-lens
v0.1.3
Published
Scaffold a Convex template onto Lens: download it, alias its Convex packages to their Lens ports, install, and (optionally) push
Readme
create-convex-lens
Scaffold a Convex template onto Lens.
Convex's own scaffolder (npm create convex) drops a template that talks to
Convex cloud. This one drops the same template with its Convex packages
aliased to their Lens ports, so it runs against SpacetimeDB instead.
All 22 templates in --list scaffold, install, deploy and build;
docs/plan/template-matrix.md in the Lens repo is the measurement, not a
claim.
npm create convex-lens@latest my-app
npm create convex-lens@latest my-app -- -t nextjs
npx create-convex-lens@latest my-app -t get-convex/convex-saasWhat it does
- Downloads the template from GitHub (a codeload ZIP, no git or degit).
- Reads the template's own
package.jsonand classifies every dependency: aliased to a Lens port, fine as it is, or blocked. - Rewrites the aliased dependencies, keeping each template's own range:
"convex": "^1.45.0"becomes"convex": "npm:@gravlens/convex@^1.45.0". That works because the Lens packages mirror the versions of the packages they stand in for, which is also what keepsnpm installhappy when something in the template peer-depends onconvex. - Strips Convex CLI options the Lens CLI has no counterpart for from the
npm scripts (cloud project configuration, preview deployments). The
options templates actually build on -
--start,--run,--until-success- are implemented, so those scripts survive unedited. - Leaves the lockfile alone. Only the aliased entries are stale in it, and
npm re-resolves exactly those (verified:
node_modules/convexis@gravlens/convex, with no copy of the real package anywhere in the tree) while everything else stays pinned to what the template was tested against. - Installs,
git inits, and optionally pushes to a local deployment.
The compatibility gate reads the downloaded package.json, so a template
this package has never heard of is still classified correctly.
Options
-t, --template <spec> template name, owner/repo, owner/repo/subdir, or a
github.com URL (default: react-vite)
--list list the template shorthands and exit
--pm <manager> npm | pnpm | yarn | bun (default: the one running this)
--no-install skip installing dependencies
--no-git skip git init and the initial commit
--push after installing, run 'convex dev --once' (needs a
running SpacetimeDB server)
--local <path> link the Lens packages from a local checkout of the
lens repo instead of npm (requires pnpm)
--lens-version <r> npm range for the aliased packages (default: the
template's own range)
--force scaffold into a non-empty directory, and continue
past a blocked dependencyWhat the gate says, and why
src/registry.ts holds the tables.
Blocked: unported components. Any @convex-dev/* package that is a
component and has no Lens port cannot mount. Ported: workflow, workpool,
batch-worker, crons, rate-limiter, action-retrier.
Convex Auth works, with two setup steps that differ from Convex cloud, because it is its own identity provider rather than a hosted one:
npx convex auth-keys # JWT_PRIVATE_KEY and JWKS, with the key id
npx convex dev --gateway # serves HTTP actions at their real pathsnpx @convex-dev/auth provisions a Convex cloud project, so it has nothing
to say to a SpacetimeDB deployment, and the JWKS it writes lacks the key id
SpacetimeDB's validator requires. The gateway matters because tokens name
CONVEX_SITE_URL as their issuer and the deployment fetches that issuer's
JWKS to validate them: it has to be an address that serves
/.well-known/, which SpacetimeDB module routes cannot. Third-party
providers (Clerk, Auth0, WorkOS) need neither step.
A template can also be wrong about its own dependencies. The Convex
SaaS starter imports @react-email/render without declaring it. Its
lockfile carries the entry, so npm installs it anyway; pnpm, which ignores
package-lock.json and hoists nothing, does not. Install that one with npm,
or add the dependency.
Working against a local checkout
To test a change to Lens itself before it is released, point the scaffolder at a checkout of this repo instead of the registry:
node packages/create-convex-lens/bin/main.js my-app \
-t react-vite --local /path/to/lens --pm pnpm --push--local writes link: dependencies, which only pnpm resolves.
