Development
Build your CLI with fast Bun loops, linked installs, and install-like smoke tests.
Use three loops while building a Crust CLI:
- run the source entry for fast iteration
- use
bun linkto test the installed command name - pack and install the publish artifact to mimic a real install
Fast Local Loop
For day-to-day work, run the source entry directly:
bun run src/cli.ts --help
bun run src/cli.ts greet world
bun run check:typesIf you used create-crust, bun run dev already points at src/cli.ts.
Also test the built resolver:
bun run build
./dist/cli --helpAlso test the built entry:
bun run build
bun run dist/cli.js --helpUse bun link
Register your CLI once from the project root:
bun linkThen link it into a separate scratch project:
mkdir -p ../my-cli-smoke
cd ../my-cli-smoke
bun init -y
bun link my-cli
my-cli --help
my-cli greet worldTo mimic a global command install while still pointing at your local package, use Bun's global link mode:
bun link -g my-cli
my-cli --helpbun link -g makes the command available from Bun's global bin directory, which you can inspect with bun pm bin -g.
Keep the scratch project outside your CLI repo. That helps catch accidental reliance on workspace paths or source-tree-only files.
bun link is for command ergonomics, not release validation:
- It uses a symlink to your source tree, not the packed files users will install.
- It can hide missing
files,bin, or build output problems. - It does not validate staged
dist/npm/packages.
Mimic a Real Install
Use bun pm pack to test the artifact you actually plan to publish.
Pack the root package and install it into a throwaway project:
bun run build
TARBALL="$(pwd)/$(bun pm pack 2>/dev/null | tail -1)"
mkdir -p ../my-cli-install
cd ../my-cli-install
bun init -y
bun add "$TARBALL"
./node_modules/.bin/my-cli --helpTo mimic a global install instead:
bun add -g "$TARBALL"
my-cli --helpIf you distribute raw binaries directly, test the built resolver:
bun run build
./dist/cli --help
./dist/cli greet worldIf you also publish the root package to npm, pack and install it the same way as the Bun runtime package example.
If your publish flow is crust build --package, the publish artifact is dist/npm/, not the repo root:
crust build --package
cd dist/npm/root
ROOT_TGZ="$(pwd)/$(bun pm pack 2>/dev/null | tail -1)"
cd ../darwin-arm64 # replace with your platform from dist/npm/manifest.json
echo "Root: $ROOT_TGZ"
echo "Platform: $PLATFORM_TGZ"Install both tarballs into a throwaway project. Replace the file: paths below with the values printed above:
mkdir -p ../my-cli-smoke
cd ../my-cli-smokeUse the platform directory that matches your host, as listed in dist/npm/manifest.json.
Recommended Workflow
- Write and iterate with
bun run src/cli.ts ... - Run
bun run check:types - Test the command name with
bun linkorbun link -g - Smoke test the publish artifact with
bun pm packor stageddist/npm/packages