User story / Problem statement
canton-dappbooster changed shape. Its three libraries are published to npm as
@bootnodedev/canton-connect, @bootnodedev/canton-dappbooster and
@bootnodedev/canton-theme. A scaffolded project must consume them from npm and never
hold their source.
The repo is now arranged so that scaffolding is almost pure deletion. pnpm links a local
library folder only when that folder's own version satisfies the declared range. Delete
the folder and the same package.json resolves from the registry instead. Nothing has to
be rewritten and no workspace file edited.
The installer's Canton config still points at the old repo and describes a tree that no
longer exists. Every field in the Part 1 table is wrong today.
Only the Canton stack changes. Everything about the EVM stack stays exactly as it is.
Expected outcome
pnpm dlx dappbooster --canton clones the current canton-dappbooster, deletes the
library folders and the repo-only tooling, and installs the three libraries from npm.
- A Canton user is asked for a project name and nothing else.
- The scaffolded project lints, typechecks, tests and passes knip, and starts from
./scripts/dev-stack.sh.
- The EVM path behaves exactly as it does today.
Acceptance criteria
Alternatives considered
Separate npm packages per stack. At two stacks that means publishing three things instead
of one and coordinating their versions, for no user-visible gain. Worth revisiting if a
third stack appears.
Technical notes
Suggested sequencing: three commits, in this order — config corrections, then the feature
removal and prepare phase, then the stack split. Keeping the restructuring separate means
a Canton regression and a refactoring failure do not arrive together.
Part 1 — correct the Canton config
In source/constants/config.ts:
| Field |
Now |
Should be |
repoUrl |
https://github.com/BootNodeDev/cn-dappbooster.git |
https://github.com/BootNodeDev/canton-dappbooster.git |
refType / ref |
branch, main |
tag-latest, matching EVM. The repo now tags releases |
packageManager |
npm |
pnpm |
envFiles |
three paths under canton-barebones, dapp/frontend and carpincho-wallet |
one entry: .env.example to .env, at the root |
postInstall |
canton-barebones/.env, npm run canton:up, npm run app:dev |
see below |
The scaffolded .env works on its defaults. The one empty value, CANTON_BACKEND_TOKEN,
is minted by the project's own dev-stack.sh, so nothing needs editing by hand before
starting.
postInstall is printed text and nothing more. Cut it to roughly:
- Docker must be running
- Run
./scripts/dev-stack.sh — the first run pulls about 10 GB
- See
README.md for the step-by-step and the wallet requirement
The project's README already covers the rest, including the fact that a CIP-0103 browser
wallet is needed and ships nowhere in the repo.
Part 2 — drop the Canton feature system
Remove all four Canton features: github, precommit, carpincho and llm. carpincho
refers to a wallet that left that monorepo entirely. The other three become unconditional,
as set out in Part 3.
Consequences to follow through:
- The wizard's install-mode step and feature step are meaningless for a stack with no features. Skip both when a stack declares none
- In non-interactive mode,
--mode and --features must be rejected for such a stack with a clear message rather than silently ignored
--info for canton reports no features
cleanupCantonFiles, patchPackageJsonCanton, pruneRemovedWorkspaces and scriptTargetsRemovedDir exist to serve that feature system. Remove whatever becomes unreachable; keep anything the EVM path still uses
createInitialCommit must survive. It is called on the Canton branch of cleanupFiles
and nowhere else, so gutting that function would silently delete it. Move it rather than
lose it: an initialised repo with everything untracked is worse than a baseline commit,
because the user cannot see what they changed after scaffolding.
While moving it, drop the hardcoded author (user.name=dAppBooster,
user.email=no-reply@dappbooster.dev) and let git use the user's own config. That name
sits in their history forever otherwise. Keep --no-verify: the scaffolded project's own
husky hooks would otherwise run against a freshly cloned tree and fail.
Features can be added back later if anyone asks for them. Nobody has.
Part 3 — a prepare phase that runs before pnpm install
The current order is CloneRepo, then Install, then FileCleanup. Only removeAfterClone
runs before the install, because it lives inside the clone step.
That is a problem for the manifest edit below: as things stand the installer would install
typedoc and postcss, then strip them from package.json afterwards, leaving
node_modules and the lockfile disagreeing with the file. Deleting pnpm-lock.yaml has
the same requirement — it must be gone before the resolve, not after.
Widen removeAfterClone into a small prepare phase driven by stack config: a list of
paths to delete and a list of package.json keys to remove, both applied before the
single pnpm install. EVM passes empty lists and behaves exactly as it does today. No
reordering of the shared step sequence.
Paths to delete:
.claude
.github
canton-connect/
canton-dappbooster/
canton-theme/
kit/
AGENTS.md
CLAUDE.md
architecture.md
renovate.json
vercel.json
dapp/frontend/AGENTS.md
dapp/frontend/CLAUDE.md
dapp/frontend/architecture.md
dapp/frontend/PROVENANCE.md
dapp/daml/PROVENANCE.md
pnpm-lock.yaml
Kept deliberately: biome, knip, commitlint, husky, gitleaks, the root README, scripts/,
dapp/daml and dapp/frontend/vercel.json. Those are ordinary hygiene tools a project
wants, and the README's steps all still work with the libraries absent.
dapp/frontend/vercel.json is working deployment example code the consumer may want, and
it pairs with dapp/frontend/api/rpc.ts: that handler exists only to be deployed as a
Vercel function, and the config carries the routing that reaches it, with its catch-all
scoped away from /api/ so it cannot answer one with index.html. Deleting the config
while keeping the handler leaves dead code and a deployment that silently does the wrong
thing. The root vercel.json still goes: that one is the reference site's build settings
and belongs to canton-dappbooster.
package.json keys to remove:
scripts: docs:build, docs:check, check:anatomy, check:versions, release, release:dry, release:version. Every one points at kit/, which is deleted
devDependencies: typedoc and postcss. Both exist only for the deleted tooling
Those two halves go together. knip counts a binary named in a package.json script as
used, so removing docs:build without also removing typedoc makes knip fail on an unused
dependency in the scaffolded project.
The test script needs no change. It globs kit/**/*.test.mjs, and node --test exits 0
on a pattern matching nothing.
Part 4 — split the stacks into their own modules
The two stacks share one step sequence but branch on stack name in several places. After
Part 2 most of that disappears, which makes this the moment to finish the job.
source/stacks/evm.ts exports a StackConfig
source/stacks/canton.ts exports a StackConfig
source/stacks/index.ts the record, stackNames, the lookup helpers
source/constants/config.ts keeps only the types and generic accessors, or those move to
source/types/types.ts.
Then remove the remaining places that know a stack by name:
operations/cleanupFiles.ts, around lines 318 and 348. Both checks exist only for the Canton feature system and fall out with Part 2
nonInteractive.ts, around line 93: flags.mode === 'default' && stack === 'evm' becomes a question about whether that stack offers a default mode, which getInstallationModes already answers
components/steps/PostInstall.tsx, around lines 175 to 180, renders three components off hardcoded stack names. Give StackConfig an optional component field: PostInstall renders that when present, and otherwise falls back to plain lines from the postInstall array. Canton's message is two lines and needs no component; EVM keeps its subgraph warning unchanged
cli.tsx's --evm and --canton shortcut flags are the CLI surface and can stay as they
are. cloneRepo, createEnvFile and installPackages are already config-driven and need
nothing.
Not in scope: separate npm packages per stack (see Alternatives considered).
Also
- Node. The scaffolded Canton project requires Node 24.15 or later; the installer declares 22. Do not raise the installer's own
engines, which would block EVM users who have no such requirement. Check the running version before cloning for Canton and fail with a plain message, because pnpm install inside the flow would otherwise fail later with a more confusing error
- The installer's README documents the Canton feature keys, the three install modes and the old post-install commands. All of that changes
source/__tests__ covers config, nonInteractive, cleanupFiles, installPackages and createEnvFile. Expect all of them to need updating
Additional context
DAPPBOOSTER_CANTON_REPO_URL and DAPPBOOSTER_CANTON_REF override the cloned repo and
ref, so the whole flow can be exercised against a branch or a fork before anything is
released.
This assumes the canton-dappbooster work is already approved and merged, so its main
branch has the shape described above and the three libraries are on npm.
User story / Problem statement
canton-dappbooster changed shape. Its three libraries are published to npm as
@bootnodedev/canton-connect,@bootnodedev/canton-dappboosterand@bootnodedev/canton-theme. A scaffolded project must consume them from npm and neverhold their source.
The repo is now arranged so that scaffolding is almost pure deletion. pnpm links a local
library folder only when that folder's own version satisfies the declared range. Delete
the folder and the same
package.jsonresolves from the registry instead. Nothing has tobe rewritten and no workspace file edited.
The installer's Canton config still points at the old repo and describes a tree that no
longer exists. Every field in the Part 1 table is wrong today.
Only the Canton stack changes. Everything about the EVM stack stays exactly as it is.
Expected outcome
pnpm dlx dappbooster --cantonclones the current canton-dappbooster, deletes thelibrary folders and the repo-only tooling, and installs the three libraries from npm.
./scripts/dev-stack.sh.Acceptance criteria
pnpm dlx dappbooster --canton --name testproj --niscaffolds a working project from the latest canton-dappbooster tagpackage.jsonhas neither the seven scripts nor typedoc and postcsspnpm installin the scaffolded project resolves the three@bootnodedev/*libraries from npm, with no path pointing into a workspace library folderpnpm lint,pnpm typecheck,pnpm testandpnpm knipall pass in the scaffolded project (knip printing configuration hints is fine, as long as it exits 0)--modeor--featureswith--cantonfails with a message naming the reasonsource/outsidestacks/andcli.tsxtests a stack by nameAlternatives considered
Separate npm packages per stack. At two stacks that means publishing three things instead
of one and coordinating their versions, for no user-visible gain. Worth revisiting if a
third stack appears.
Technical notes
Suggested sequencing: three commits, in this order — config corrections, then the feature
removal and prepare phase, then the stack split. Keeping the restructuring separate means
a Canton regression and a refactoring failure do not arrive together.
Part 1 — correct the Canton config
In
source/constants/config.ts:repoUrlhttps://github.com/BootNodeDev/cn-dappbooster.githttps://github.com/BootNodeDev/canton-dappbooster.gitrefType/refbranch,maintag-latest, matching EVM. The repo now tags releasespackageManagernpmpnpmenvFilesdapp/frontendand carpincho-wallet.env.exampleto.env, at the rootpostInstallcanton-barebones/.env,npm run canton:up,npm run app:devThe scaffolded
.envworks on its defaults. The one empty value,CANTON_BACKEND_TOKEN,is minted by the project's own
dev-stack.sh, so nothing needs editing by hand beforestarting.
postInstallis printed text and nothing more. Cut it to roughly:./scripts/dev-stack.sh— the first run pulls about 10 GBREADME.mdfor the step-by-step and the wallet requirementThe project's README already covers the rest, including the fact that a CIP-0103 browser
wallet is needed and ships nowhere in the repo.
Part 2 — drop the Canton feature system
Remove all four Canton features:
github,precommit,carpinchoandllm.carpinchorefers to a wallet that left that monorepo entirely. The other three become unconditional,
as set out in Part 3.
Consequences to follow through:
--modeand--featuresmust be rejected for such a stack with a clear message rather than silently ignored--infofor canton reports no featurescleanupCantonFiles,patchPackageJsonCanton,pruneRemovedWorkspacesandscriptTargetsRemovedDirexist to serve that feature system. Remove whatever becomes unreachable; keep anything the EVM path still usescreateInitialCommitmust survive. It is called on the Canton branch ofcleanupFilesand nowhere else, so gutting that function would silently delete it. Move it rather than
lose it: an initialised repo with everything untracked is worse than a baseline commit,
because the user cannot see what they changed after scaffolding.
While moving it, drop the hardcoded author (
user.name=dAppBooster,user.email=no-reply@dappbooster.dev) and let git use the user's own config. That namesits in their history forever otherwise. Keep
--no-verify: the scaffolded project's ownhusky hooks would otherwise run against a freshly cloned tree and fail.
Features can be added back later if anyone asks for them. Nobody has.
Part 3 — a prepare phase that runs before pnpm install
The current order is CloneRepo, then Install, then FileCleanup. Only
removeAfterCloneruns before the install, because it lives inside the clone step.
That is a problem for the manifest edit below: as things stand the installer would install
typedoc and postcss, then strip them from
package.jsonafterwards, leavingnode_modulesand the lockfile disagreeing with the file. Deletingpnpm-lock.yamlhasthe same requirement — it must be gone before the resolve, not after.
Widen
removeAfterCloneinto a small prepare phase driven by stack config: a list ofpaths to delete and a list of
package.jsonkeys to remove, both applied before thesingle
pnpm install. EVM passes empty lists and behaves exactly as it does today. Noreordering of the shared step sequence.
Paths to delete:
Kept deliberately: biome, knip, commitlint, husky, gitleaks, the root README,
scripts/,dapp/damlanddapp/frontend/vercel.json. Those are ordinary hygiene tools a projectwants, and the README's steps all still work with the libraries absent.
dapp/frontend/vercel.jsonis working deployment example code the consumer may want, andit pairs with
dapp/frontend/api/rpc.ts: that handler exists only to be deployed as aVercel function, and the config carries the routing that reaches it, with its catch-all
scoped away from
/api/so it cannot answer one withindex.html. Deleting the configwhile keeping the handler leaves dead code and a deployment that silently does the wrong
thing. The root
vercel.jsonstill goes: that one is the reference site's build settingsand belongs to canton-dappbooster.
package.jsonkeys to remove:scripts:docs:build,docs:check,check:anatomy,check:versions,release,release:dry,release:version. Every one points atkit/, which is deleteddevDependencies:typedocandpostcss. Both exist only for the deleted toolingThose two halves go together. knip counts a binary named in a
package.jsonscript asused, so removing
docs:buildwithout also removing typedoc makes knip fail on an unuseddependency in the scaffolded project.
The
testscript needs no change. It globskit/**/*.test.mjs, andnode --testexits 0on a pattern matching nothing.
Part 4 — split the stacks into their own modules
The two stacks share one step sequence but branch on stack name in several places. After
Part 2 most of that disappears, which makes this the moment to finish the job.
source/constants/config.tskeeps only the types and generic accessors, or those move tosource/types/types.ts.Then remove the remaining places that know a stack by name:
operations/cleanupFiles.ts, around lines 318 and 348. Both checks exist only for the Canton feature system and fall out with Part 2nonInteractive.ts, around line 93:flags.mode === 'default' && stack === 'evm'becomes a question about whether that stack offers a default mode, whichgetInstallationModesalready answerscomponents/steps/PostInstall.tsx, around lines 175 to 180, renders three components off hardcoded stack names. GiveStackConfigan optionalcomponentfield: PostInstall renders that when present, and otherwise falls back to plain lines from thepostInstallarray. Canton's message is two lines and needs no component; EVM keeps its subgraph warning unchangedcli.tsx's--evmand--cantonshortcut flags are the CLI surface and can stay as theyare.
cloneRepo,createEnvFileandinstallPackagesare already config-driven and neednothing.
Not in scope: separate npm packages per stack (see Alternatives considered).
Also
engines, which would block EVM users who have no such requirement. Check the running version before cloning for Canton and fail with a plain message, becausepnpm installinside the flow would otherwise fail later with a more confusing errorsource/__tests__covers config, nonInteractive, cleanupFiles, installPackages and createEnvFile. Expect all of them to need updatingAdditional context
DAPPBOOSTER_CANTON_REPO_URLandDAPPBOOSTER_CANTON_REFoverride the cloned repo andref, so the whole flow can be exercised against a branch or a fork before anything is
released.
This assumes the canton-dappbooster work is already approved and merged, so its
mainbranch has the shape described above and the three libraries are on npm.