archapp-cli
v0.1.0
Published
CLI for creating and managing Arch applications.
Maintainers
Readme
archapp
Developer CLI for creating and managing Arch applications.
Full command reference: docs/cli.md
Usage
archapp create my-app --type worker # Next.js frontend, Cloudflare Worker
archapp create my-app --type container # FastAPI backend, Cloudflare Container
archapp create my-app # prompts for whatever's missing
archapp create # prompts for name and typecreate clones one app from arch-starter directly into
the project root — there's no monorepo wrapper, ./my-app is the app:
--type workerclonesarch-starter/apps/frontendinto./my-app--type containerclonesarch-starter/apps/fastapi-backendinto./my-app
The cloned app is renamed to match my-app (package/pyproject name, README
references), Cloudflare deploy config is wired up (below), dependencies are
installed (pnpm install, plus uv sync for the container type), and git is
initialized.
Cloudflare deploy wiring
create generates the following on top of the cloned template, so this
doesn't have to live in arch-starter itself:
- worker —
wrangler.jsonc+open-next.config.tsat the project root, Cloudflare Worker config for the Next.js app via@opennextjs/cloudflare(added topackage.jsonalong withdeploy/cf:build/previewscripts). Worker name:<app>-web. - container —
wrangler.jsonc,src/index.ts(a Worker + Durable-Object-backedContainerclass via@cloudflare/containers), and aDockerfilethat builds the cloned FastAPI app viauv(installsuv, copiespyproject.toml/uv.lock/README.md/src/<name>, runsuv sync --frozen --no-dev, serves withuvicorn). The Worker'ssrc/index.tsand the cloned Python package'ssrc/<name>/live side by side under the samesrc/— no collision, and the Dockerfile only copies the Python subdirectory in. Worker name:<app>-api. Apnpm-workspace.yamlis written approving theesbuild/workerdbuild scripts wrangler needs (the worker type doesn't need this — the cloned frontend template already ships its own). The bundled admin SPA atfrontend/is not built into the image — build it separately if you need it served in production. .github/workflows/deploy.yml— on push tomain: installs deps, then runspnpm run deploy, usingCLOUDFLARE_API_TOKEN/CLOUDFLARE_ACCOUNT_IDrepo secrets.gitignoreentries for.wrangler/.open-next(worker) or.wrangler/node_modules(container) are appended to the cloned template's own.gitignoreif missing
This logic lives in src/lib/cloudflare-deploy.js + src/lib/project-extras.js
and runs regardless of --template, so any starter gets the same wiring.
Deploy scripts are always invoked as pnpm run deploy, not the bare
pnpm deploy shorthand — deploy is also a built-in pnpm command, and a
bare invocation can be captured by that instead of running the package's own
script.
Adding an app to an existing monorepo
archapp add worker <name> # Hono app on a plain Cloudflare Worker
archapp add container <name> # e.g. FastAPI, running in a Cloudflare ContainerThis is a separate, older feature, unrelated to create's output today: it
must be run from the root of a monorepo with an app.manifest.json (a layout
create no longer produces — see above), and scaffolds a bare-bones second
app into apps/<name> there, registering it in the manifest.
worker— bare Hono app (no auth/DB wiring), with a<project>-<name>Worker name.container— a Worker + Durable-Object-backedContainerclass (via@cloudflare/containers) that proxies to aDockerfile'd bare hello-world FastAPI app. Needed because Python on Workers itself is still limited; the container can run anything the Dockerfile builds. Requires Docker locally forwrangler dev/deployto build the image.
Both register a deploy script (pnpm --filter <name> run deploy) and an
entry in app.manifest.json — for container apps, that entry's
resources.containers records the Durable Object class name so future
tooling knows what to tear down.
Running scripts
archapp run executes a script from the current app's package.json. It
detects the project type and maps common aliases to the correct script name.
archapp run preview # worker (Next.js): pnpm run preview
archapp run build # worker: pnpm run cf:build
archapp run dev # any app: pnpm run dev
archapp run deploy # any app: pnpm run deploy
archapp run db:migrate # any script in package.json
archapp run dev --app api # monorepo: pnpm --filter api run devRun from an app directory created with archapp create, or from a monorepo
root with --app <name>.
| Alias | Worker (Next.js) | Container (FastAPI) | Monorepo worker |
|-------|------------------|---------------------|-----------------|
| build | cf:build | frontend/ npm build* | not supported |
| preview | preview | use dev | use dev |
| dev | dev | dev | dev |
| deploy | deploy | deploy | deploy |
*On container apps, archapp run build runs npm run build in the optional
frontend/ directory when that directory has a build script.
Any other script name (e.g. db:migrate, typecheck) is passed through if it
exists in package.json. See docs/cli.md for the full reference.
Local development (not yet published)
node bin/archapp.js create my-app --type workeror link it globally:
pnpm link --global
archapp create my-app --type workerTemplate source
By default, create looks for a sibling arch-starter directory (i.e.
../arch-starter relative to this repo) — the setup used during local
development of both repos on the same machine. Override it with:
archapp create my-app --type worker --template /path/to/other-starter
archapp create my-app --type worker --template https://github.com/org/repo.git
ARCHAPP_TEMPLATE=/path/to/starter archapp create my-app --type workerA remote (--template <url>) is cloned into a temporary directory first,
since only one apps/* subdirectory is copied out of it — not the whole repo.
Roadmap
create, add, and run are implemented — see docs/cli.md for
the full command reference. Planned next: archapp destroy <app> (tear down
Cloudflare resources), template updates for existing projects, and reconciling
add with create's flat, monorepo-free output (today they produce
incompatible project shapes).
