Minimal Project
Use caatinga init --minimal when you want a Soroban contract and CLI workflow without a bundled frontend. You choose the UI stack later — React, Next.js, Svelte, or no browser at all.
Not sure this is the right path? See Choosing a project scaffold.
When to use
- Contract and CLI first; frontend is a separate decision
- Integrating Caatinga into an existing app or monorepo
- Backend scripts, CI, or indexer workflows that only need deploy + read/invoke
- You do not want wallet stubs or Vite config copied into the repo on day one
For a ready-made Vite + React dApp, use Template project instead.
Scaffold
npx caatinga init my-contract-app --minimal
cd my-contract-app
npm install
npx caatinga doctor--empty is an alias for --minimal.
What gets generated
| Path / file | Purpose |
|---|---|
caatinga.config.ts | Contract app, networks — no frontend block |
caatinga.artifacts.json | Empty testnet entry until deploy |
contracts/app/ | Soroban stub: hello(), version() |
package.json | Scripts: build, deploy, doctor, read:hello, read:version |
Not included: src/, Vite, React, wallet stubs, or TypeScript bindings.
CLI workflow
npx caatinga build app
npx caatinga deploy app --network testnet --source alice
npx caatinga read app.version --network testnet
npx caatinga read app.hello --network testnetOr use the npm scripts:
npm run build
npm run deploy
npm run read:version
npm run read:helloDeploy writes the on-chain contractId to caatinga.artifacts.json. Reads and deploys need a local Stellar CLI identity (--source alice). Public G... addresses are rejected.
Read vs invoke
The stub contract ships read-only methods:
hello()— returns Soroban Symbolhelloversion()— returns1
Use caatinga read (or client.read() in the browser) for these methods. Use caatinga invoke only after you add state-changing methods to contracts/app/src/lib.rs.
For caatinga read, --source is optional on the CLI: Caatinga resolves CAATINGA_SOURCE or defaults to alice.
Soroban Symbol parameters are generated as TypeScript string values with host-specific restrictions — see Soroban types.
Adding a frontend later
init --minimal does not pick a UI framework. After deploy, wire any stack you prefer:
Config — add
frontend.bindingsOutputtocaatinga.config.ts(frameworkis metadata only):tsfrontend: { framework: "vite-react", bindingsOutput: "./src/contracts/generated" }Bindings —
npx caatinga deploy appgenerates bindings automatically, or recover with:bashnpx caatinga generate app --network testnetPackages — install
@caatinga/client,@caatinga/core, and a wallet adapter (@creit.tech/stellar-wallets-kitor custom). See Client and Wallets.Wiring — keep a dedicated
src/caatinga.tswith static imports of artifacts and generated bindings. Import that module from your UI. See Project layout.Wallet stubs — if you use Stellar Wallets Kit with Vite/webpack, apply helpers from
@caatinga/client/vite(walletStubViteAliases,walletStubOverrides). Copy stub files fromreact-vite-counteror follow Wallets — custom Vite projects.Read vs invoke in the browser — use
client.contract("app").read()for getters;invoke()only for state-changing methods. See Read and Simulate.
The react-vite-counter template is a full reference implementation, not a requirement.
Next steps
- Client — browser interop with generated bindings
- Soroban types — Symbol vs string footguns
- ZK project — add Groth16 circuits to an existing minimal project with
caatinga zk init