typescript-plugin/skills/bun-publishing/SKILL.md
Publish npm packages built with Bun: package.json config, CLI tool packaging, provenance signing, release automation. Use when setting up `publishConfig`/`files`/`bin`, packaging a CLI, enabling `--provenance`, or wiring release-please.
npx skillsauth add laurigates/claude-plugins bun-publishingInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
| Scenario | Use this skill | Alternative |
|----------|---------------|-------------|
| Configuring package.json for npm publishing | Yes | N/A |
| Publishing a package to npm registry | Yes | N/A |
| Setting up CLI tool packaging with bin | Yes | N/A |
| Configuring provenance signing | Yes | N/A |
| Setting up release-please automation | Yes | N/A |
| Validating tarball contents before publish | Yes | N/A |
| Installing or updating dependencies | No - use bun-package-manager | bun-add for quick additions |
| Building/bundling before publish | No - use bun-development | bun-build for quick builds |
Publishing npm packages built with Bun:
{
"name": "@org/package-name",
"version": "1.0.0",
"description": "Package description",
"main": "build/index.js",
"type": "module",
"publishConfig": {
"access": "public"
},
"files": [
"build/",
"README.md",
"LICENSE"
],
"scripts": {
"build": "tsc && chmod +x build/index.js",
"prepublishOnly": "bun run build"
},
"engines": {
"node": ">=20.0.0",
"bun": ">=1.0.0"
}
}
| Field | Purpose |
|-------|---------|
| publishConfig.access | public required for scoped packages |
| files | Whitelist of files/dirs to include in tarball |
| main | Entry point for CommonJS/ES import |
| type | module for ESM, commonjs for CJS |
| engines | Runtime version requirements |
| prepublishOnly | Runs before npm publish |
Scoped packages (@org/name) require explicit public access:
{
"name": "@myorg/mypackage",
"publishConfig": {
"access": "public"
}
}
Or use the CLI flag:
npm publish --access public
{
"bin": {
"mycli": "build/index.js"
}
}
For single-command packages:
{
"bin": "build/index.js"
}
Entry point requires shebang and executable permission:
#!/usr/bin/env node
// build/index.js
import { main } from "./main.js";
main();
Build script must set permissions:
{
"scripts": {
"build": "tsc && chmod +x build/index.js"
}
}
build-prod:
rm -rf build
tsc --declaration --sourceMap
chmod +x build/index.js
publish: build-prod
npm publish --access public
# Standard publish (runs prepublishOnly)
npm publish
# Scoped package (requires --access public)
npm publish --access public
# Dry run to verify contents
npm publish --dry-run
# View what would be published
npm pack --dry-run
Supply chain security via npm provenance:
npm publish --provenance --access public
Requires:
id-token: write permission in workflow{
"files": [
"build/",
"README.md",
"LICENSE"
]
}
| Include | Examples |
|---------|----------|
| Build output | build/, dist/ |
| Type definitions | *.d.ts (usually in build) |
| Documentation | README.md, LICENSE |
| Config scripts | User-facing setup scripts |
Already excluded by npm (no need to list):
node_modules/.git/.env**.logExplicitly exclude via .npmignore if needed:
src/
tests/
*.test.ts
.github/
.github/workflows/release-please.yml:
name: Release Please
on:
push:
branches: [main]
permissions:
contents: write
pull-requests: write
id-token: write
jobs:
release-please:
runs-on: ubuntu-latest
outputs:
release_created: ${{ steps.release.outputs.release_created }}
steps:
- uses: google-github-actions/release-please-action@v4
id: release
with:
release-type: node
package-name: mypackage
publish:
needs: release-please
if: ${{ needs.release-please.outputs.release_created == 'true' }}
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 24
registry-url: https://registry.npmjs.org
- uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- run: bun install --frozen-lockfile
- run: bun run build
- run: npm publish --provenance --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
| Commit Type | Version Bump |
|-------------|--------------|
| feat: | Minor (1.x.0) |
| fix: | Patch (1.0.x) |
| feat!: or BREAKING CHANGE: | Major (x.0.0) |
| chore:, docs:, refactor: | No bump |
{
"scripts": {
"prepublishOnly": "bun run build"
}
}
# Type check
bun run tsc --noEmit
# Lint
bun run check
# Test
bun test
# Build
bun run build
# Verify tarball contents
npm pack --dry-run
Complete metadata for npm and GitHub:
{
"repository": {
"type": "git",
"url": "https://github.com/org/repo.git"
},
"homepage": "https://github.com/org/repo#readme",
"bugs": {
"url": "https://github.com/org/repo/issues"
},
"keywords": ["keyword1", "keyword2"],
"author": "Name <email>",
"license": "MIT"
}
| Context | Command |
|---------|---------|
| Preview tarball | npm pack --dry-run |
| Preview publish | npm publish --dry-run |
| Scoped publish | npm publish --access public |
| Provenance | npm publish --provenance --access public |
| Check outdated | npm outdated |
| View package | npm view @org/pkg |
| Flag | Description |
|------|-------------|
| --access public | Required for scoped packages |
| --provenance | Enable supply chain provenance |
| --dry-run | Preview without publishing |
| --tag <tag> | Publish with dist-tag (e.g., beta) |
| Script | When It Runs |
|--------|--------------|
| prepublish | Before pack and publish (deprecated) |
| prepublishOnly | Before publish only |
| prepack | Before pack and publish |
| postpack | After pack |
| postpublish | After publish |
| Variable | Purpose |
|----------|---------|
| NODE_AUTH_TOKEN | npm authentication |
| NPM_TOKEN | Alternative npm token name |
Scoped package 402 error:
# Add --access public for scoped packages
npm publish --access public
Missing files in tarball:
# Check what's included
npm pack --dry-run
# Verify files array in package.json
Binary not executable after install:
# Ensure shebang in entry point
#!/usr/bin/env node
# Ensure chmod in build script
chmod +x build/index.js
tools
Scaffold a new ComfyUI custom-node repo (pyproject, CI, release-please, vitest+pytest, JS extension skeleton) in the picker/gesture vein. Use when bootstrapping or init-ing a comfyui node pack.
tools
Orchestrate a ComfyUI node pack from idea to registry: scaffold, create + seed the repo, open the gitops adoption PR. Use when releasing or spinning up a new comfyui node pack.
testing
macOS EndpointSecurity/EDR high CPU & battery drain. Use when Kandji ESF / XProtect pegs a core; trace the exec storm via powermetrics + eslogger.
development
odiff pixel-by-pixel image diffing. Use when comparing screenshots, detecting visual regressions, diffing before/after PNGs, asserting golden images.