Documents › Developer Guide
This document is a quick reference for maintainers and frequent contributors. It complements the contributor guide (which is contributor-facing) and contains deeper, actionable instructions for setting up, testing, and developing the project. We use Husky to manage our git hooks. When you install dependencies, the environment is automatically configured. See the Hooks section below for more info.
# clone
git clone https://github.com/cashubtc/cashu-ts.git
cd cashu-ts
# install exact dependencies used by CI
npm ci
# prepare browser dependencies for integration tests (one-time)
npm run test:prepare
This repository no longer uses a separate development branch. All development now happens directly against main.
The project will continue to support the last prior major release on a version branch. At the time of this change
main tracks v3, while the v2 linage exists on v2-dev.
If you are backporting fixes to the v2 line, please open pull requests against the v2-dev branch instead.
Notes:
npm ci requires a package-lock.json and produces a reproducible node_modules tree.package.json (engine: node >=22.4.0). Use nvm, volta, or asdf to pin your local Node version.npm ci after switching major branchesWhen switching between major branches (for example main for v3 and v2-dev for v2) the lockfile and installed dependencies can differ. This frequently causes confusing failures when compiling or running api-extractor.
Always run a clean install after switching major branches to ensure node_modules matches the checked-in lockfile:
# after checkout
npm ci
If you still see strange build or extractor errors, do a full refresh of dependencies:
rm -rf node_modules
npm ci
This callout is important — please don't skip it when moving between major branches, it saves a lot of time debugging mysterious build/test failures.
npm (node package manager), git, optional nvm/volta for Node version management.npm run test:prepare).During the install process husky was installed and setup for pre-commit, pre-push, and commit-msg hooks.
We also automatically configured your local git config commit.template to use our project's .gitmessage.
This project follows the Conventional Commits specification. This is required because it powers our automated versioning and changelog generation.
<type>(<scope>): <description>feat: A new feature (triggers a MINOR version bump).fix: A bug fix (triggers a PATCH version bump).docs: Documentation changes only.chore: Maintenance tasks or library updates..gitmessage template to help you structure your messages. This is automatically configured as your local commit.template when you run npm install.If your message doesn't fit the format, the commit-msg hook will prevent the commit.
If your commit fails the commitlint check, don't worry—you don't have to retype it!
The Quick Fix:
Git saves your last failed commit message in .git/COMMIT_EDITMSG. You can quickly recover it with:
git commit -t .git/COMMIT_EDITMSG
We previously offered hooks as opt-in. If you had that configured we offer a migrate-hooks command.
npm run migrate-hooks
This runs npm run uninstall-hooks and npm install.
pre-commit: quick feedback (lint + format) — fast to avoid blocking developers.
FULL_PRECOMMIT=1 for a single commit when you want the full suite locally.pre-push: runs full PR checks (npm run prtasks) to ensure the full suite runs before pushing.This keeps commits fast while ensuring pushes execute the heavier checks.
The repo includes a convenience script:
npm run prtasks
This runs (in order): lint, format, api:update (compile + api-extractor), tests, and git status.
Caution: api:update can modify generated files (e.g. API reports). Inspect and commit any intended changes.
Many maintainers prefer to run the full PR checks locally before pushing. A common, reliable workflow:
# from the repo root
DEV=1 make cdk-stable-up
# or DEV=1 make nutshell-stable-up
npm run prtasks
npm run test-integration
3a. (Optional but recommended) Run the consumer smoke tests used by CI:
# runs all consumer smoke tests (bundler, commonjs, iife, nodenext, reactnative)
npm run test:consumer
Note: the consumer smoke tests are run in CI but are intentionally not part of prtasks to avoid adding noise to every local run; running npm run test:consumer locally before pushing helps reproduce CI behavior.
The test:consumer aggregator runs the following scripts (you can run them individually):
npm run test:bundler — smoke test using the bundler consumernpm run test:commonjs — smoke test for CommonJS consumersnpm run test:iife — smoke test for IIFE (standalone) buildnpm run test:nodenext — smoke test for Node ESM consumersnpm run test:reactnative — smoke test for React Native consumerRun the individual script if you want to isolate failures or speed up debugging.
DEV=1 make cdk-stable-down
# or DEV=1 make nutshell-stable-down
This pattern (run npm run prtasks and integration tests against a local mint) gives fast, reproducible results and avoids surprises in CI.
The repository provides Makefile targets that make it easy to spin up the most popular cashu mints (currently cdk and nutshell). These are used in the CI for integration testing and made available locally. Use the Makefile as the single source of truth for the pinned Docker image versions.
Spin up / tear down locally
# start the mint (uses Makefile defaults unless you override)
DEV=1 make cdk-stable-up
# stop the mint
DEV=1 make cdk-stable-down
# start nutshell
DEV=1 make nutshell-stable-up
# stop nutshell
DEV=1 make nutshell-stable-down
# run a specific mint image with a custom container name
# NOTE: cdk-up is the base target, cdk-stable-up/cdk-rc-up use the stable/rc values
CDK_IMAGE=cashubtc/mintd:0.13.4 CDK_NAME=my-local-mint DEV=1 make cdk-up
make cdk-stable-up / make nutshell-stable-up) so the runtime behavior in CI matches local usage.latest) so PRs will update numeric tags.npm run test-integration.npm cinpm run test:prepareDEV=1 make cdk-stable-up (and/or DEV=1 make nutshell-stable-up, DEV=1 make cdk-rc-up, DEV=1 make nutshell-rc-up)npm run test-integrationDEV=1 make cdk-stable-down / DEV=1 make nutshell-stable-downnpm run api:check to create a temporary API report and compare it to the recorded status-quo at /etc/cashu-ts.api.md.npm run api:update to update the /etc status-quo when a public API change is intended.When running api:update locally:
npm run api:update
# inspect changes under /etc
git add /etc/cashu-ts.api.md
git commit -m "docs(api): update API report"
If api:update modifies generated code or types, run the test/build steps and ensure CI passes.
Run unit tests (node + browser) locally:
npm test
The npm test script runs Vitest with coverage enabled (--coverage) and emits reports
into the coverage/ directory.
After the run you can open the HTML report locally (coverage/index.html) in
your browser to inspect per-file metrics.
CI also publishes code coverage; the project site hosts the latest report (see the README badge/link for the public report).
If a test requires Node-only features, name the file with .node. in the filename
(for example cbor.node.test.ts). The Vite/Vitest configuration will then
skip browser testing for that file and run it only in the Node environment.
Likewise, you can use .browser. in the filename to mark a test as
browser-only (we currently don't have any browser-only tests, but the convention is supported).
Run only node tests or a single test file with vitest (useful for rapid iteration):
npx vitest --run --filter <pattern>
npm run test:prepare
# then run the integration tests
npm run test-integration
If tests are flaky locally, run with increased verbosity or use --run --inspect / --watch where supported.
npm install <pkg> --save
# or for dev dependencies
npm install <pkg> --save-dev
package-lock.json (CI will use that exact lockfile).npm ci.Cashu-TS uses semantic versioning.
The repository uses a single primary development branch, main, which represents the current major release (v3).
All new development is merged into main via pull requests.
The previous major version (v2) is supported via a long-lived maintenance branch, which is used only for critical fixes.
If you need to backport a feature to v2, open a separate PR targeting v2-dev (do not mix both in a single PR).
Releases are automated and managed by CI. Maintainers should not create releases manually.
We use release-please to automate our release cycle.
main is analyzed by release-please.main.feat and fix commits since the last releaseCHANGELOG.mdfeat → minor version bumpfix → patch version bumpMerging the Release PR is the release action. No additional steps are required.
If you see strange compile or api-extractor errors after switching branches: run npm ci to ensure node_modules matches the checked-in lockfile. If problems persist, try removing node_modules and running npm ci again.
To reproduce CI locally (fast): run npm run prtasks. This runs the same suite used for PRs and helps surface issues that CI would catch.
Feel free to join the matrix server or telegram channel