Key Insight: Use Bun's package manager for modules, not just npm packages!
Instead of git-cloning modules like we planned, use Bun's package manager:
# Old plan (git-based):
git clone https://github.com/user/commando-module-aws ~/.commando/modules/aws
# New plan (npm-based):
cd ~/.commando
bun add @commando-modules/aws
# Or even simpler (from project):
cd my-project
cmdo module add aws
# → Installs to ~/.commando/node_modules/@commando-modules/awsWhy this is brilliant:
- ✅ Versioning (semantic versioning, not git SHAs)
- ✅ Dependency resolution (modules can depend on other modules)
- ✅ Lock files (reproducible installs)
- ✅ Security auditing (
bun pm audit) - ✅ Updates (
bun update @commando-modules/aws) - ✅ Private registries (for your company modules)
Publish modules to npm:
# Module author publishes
cd commando-module-aws
bun publish
# Users install
cmdo module add aws
# → bun add @commando-modules/awsPros:
- ✅ Standard tooling
- ✅ Version management
- ✅ Easy discovery
- ✅ CDN distribution
Cons:
⚠️ npm supply chain risks (need vetting)⚠️ Namespace squatting (@commando-modules/...)
Install directly from git:
cmdo module add https://github.com/user/commando-module-aws
# → bun add github:user/commando-module-awsSupports:
- GitHub:
github:user/repo - GitLab:
gitlab:user/repo - Bitbucket:
bitbucket:user/repo - Git URLs:
git+https://github.com/user/repo.git#v1.2.3
Pros:
- ✅ No npm needed
- ✅ Version via git tags
- ✅ Private repos (via SSH keys)
Cons:
⚠️ No central registry⚠️ Harder to discover modules
Official modules → npm (@commando-modules/...) Community modules → git URLs Private modules → Private npm registry or git
# Official (vetted)
cmdo module add aws
# → bun add @commando-modules/aws
# Community (git)
cmdo module add https://github.com/someuser/commando-module-custom
# Private (company registry)
cmdo module add @mycompany/commando-module-internal
# → Uses private npm registry# Bun is FAST (faster than npm, yarn, pnpm)
bun add picocolors pino ora
# Installs in ~100ms{
"workspaces": [
"modules/*"
]
}Use case: Develop multiple modules together
~/.commando/
├── package.json
├── node_modules/
└── modules/
├── aws/
│ └── package.json
└── kubernetes/
└── package.json
# bun.lockb ensures reproducible installs
bun install
# Commit to git
git add bun.lockb# Add dependency
bun add picocolors
# Add dev dependency
bun add -d bun-types
# Remove dependency
bun remove picocolors
# Update all
bun update
# Update specific package
bun update picocolors
# List installed
bun pm ls
# Check for outdated
bun pm outdated# Check for vulnerabilities
bun pm audit
# Show dependency tree
bun pm ls --allcmdo module add aws
cmdo module add github:user/commando-module-custom
cmdo module add https://github.com/user/repo.git#v1.2.3Implementation:
// lib/module-manager.ts
export async function installModule(spec: string) {
const paths = getCommandoPaths();
// Change to commando installation directory
process.chdir(paths.data);
// Use Bun to install
if (spec.startsWith('http') || spec.includes(':')) {
// Git URL
await $`bun add ${spec}`;
} else {
// npm package
await $`bun add @commando-modules/${spec}`;
}
console.log(`✓ Installed module: ${spec}`);
}cmdo module listShows:
Installed modules:
aws@2.1.0 (from npm)
kubernetes@1.5.2 (from npm)
custom@1.0.0 (from github:user/custom)
Available commands:
aws:sync, aws:invalidate, aws:costs
k8s:deploy, k8s:logs, k8s:rollback
custom:foo, custom:bar
# Update all modules
cmdo module update
# Update specific module
cmdo module update aws
# Check for updates
cmdo module outdatedImplementation:
export async function updateModules(moduleName?: string) {
const paths = getCommandoPaths();
process.chdir(paths.data);
if (moduleName) {
await $`bun update @commando-modules/${moduleName}`;
} else {
await $`bun update`;
}
console.log('✓ Modules updated');
}cmdo module auditShows vulnerabilities in installed modules:
Auditing modules...
Found 2 vulnerabilities:
High: Prototype pollution in lodash@4.17.19
Fix: bun update lodash
Low: ReDoS in semver@5.7.0
Fix: bun update semver
Run 'cmdo module update' to fix.
cmdo module remove aws@commando-modules/aws/
├── package.json
├── module.ts # Main export
├── commands/
│ ├── sync.ts
│ ├── invalidate.ts
│ └── costs.ts
├── lib/
│ └── aws-helpers.ts
└── README.md
package.json:
{
"name": "@commando-modules/aws",
"version": "2.1.0",
"type": "module",
"main": "module.ts",
"exports": {
".": "./module.ts"
},
"keywords": ["commando", "commando-module", "aws"],
"dependencies": {
"picocolors": "^1.0.0"
},
"peerDependencies": {
"@commando/core": "^2.0.0"
}
}module.ts:
import type { CommandoConfig } from '@commando/core';
import { $ } from 'bun';
export default {
commands: {
'aws:sync': {
description: 'Sync to S3',
execute: async (args) => {
const bucket = args[0];
await $`aws s3 sync . s3://${bucket}/`;
}
},
'aws:costs': {
description: 'Show AWS costs',
execute: async () => {
const result = await $`aws ce get-cost-and-usage ...`.json();
console.log(result);
}
}
}
} satisfies Partial<CommandoConfig>;# Only update patch versions (1.2.x)
cmdo module update --patch
# Check what would update first
cmdo module outdated# Show what would change
cmdo module update --dry-run
# Review changelog
cmdo module changelog aws
# Then update
cmdo module update aws{
"dependencies": {
"@commando-modules/aws": "^2.1.0", // Allow 2.x.x
"@commando-modules/k8s": "~1.5.0" // Allow 1.5.x only
}
}# Add to cron or CI
cmdo module audit --json > /tmp/audit.json
# Alert if vulnerabilities found
if [ -s /tmp/audit.json ]; then
notify "Security vulnerabilities in commando modules!"
fiFor company-internal modules:
# Configure private registry
echo "registry = \"https://npm.company.com\"" >> ~/.bunfig.toml
# Or per-project
cat > ~/.commando/.bunfig.toml <<EOF
[install]
scopes = {
"@mycompany" = { url = "https://npm.company.com" }
}
EOFcd my-company-module
bun publish --registry https://npm.company.comcmdo module add @mycompany/commando-module-internal
# → Uses private registryhttps://commando-modules.dev
Lists vetted modules:
- @commando-modules/aws
- @commando-modules/kubernetes
- @commando-modules/terraform
- @commando-modules/docker
Each with:
- Version history
- Security audit status
- Download stats
- Documentation
- Source code link
cmdo module search aws
cmdo module search kubernetesImplementation:
export async function searchModules(query: string) {
// Search npm registry
const response = await fetch(
`https://registry.npmjs.org/-/v1/search?text=keywords:commando-module+${query}`
);
const results = await response.json();
for (const pkg of results.objects) {
console.log(`${pkg.package.name}@${pkg.package.version}`);
console.log(` ${pkg.package.description}`);
}
}Modules have their own node_modules:
~/.commando/
└── node_modules/
├── @commando-modules/
│ ├── aws/
│ │ ├── module.ts
│ │ └── node_modules/
│ │ └── aws-sdk/
│ └── kubernetes/
│ ├── module.ts
│ └── node_modules/
│ └── @kubernetes/client-node/
└── picocolors/
Benefits:
- ✅ Modules can use different versions of same dep
- ✅ No global dependency conflicts
- ✅ Clear ownership
# Just add dependencies manually
cd ~/.commando
bun add picocolorscmdo module add aws
# → Calls bun add under the hood- Publish official @commando-modules/aws
- Build commando-modules.dev website
- Community contributions
| Feature | Git Modules | npm Modules | Winner |
|---|---|---|---|
| Versioning | Git tags | Semver | npm |
| Dependencies | Manual | Automatic | npm |
| Updates | git pull |
bun update |
npm |
| Security audit | Manual | bun pm audit |
npm |
| Private modules | SSH keys | Private registry | Tie |
| Discovery | README lists | npm search | npm |
| Offline install | Clone once | Lock file | Tie |
Verdict: npm-based is better for everything except trust.
Vetted and maintained by commando team:
- ✅ Code review required
- ✅ Security audit before publish
- ✅ Locked down npm publish access
- ✅ Signed commits
Use at your own risk:
⚠️ Not vetted by commando team⚠️ Review code before use⚠️ Pin to specific git SHA
Your company's responsibility:
- Use internal npm registry
- Internal code review process
- Internal security scanning
- Add
getCommandoPaths().modules=node_modules/@commando-modules - Module search path: project > user > system
- Load modules from
node_modules/@commando-modules/*
-
cmdo module add <name|url> -
cmdo module remove <name> -
cmdo module list -
cmdo module update [name] -
cmdo module audit -
cmdo module search <query> -
cmdo module outdated
- Create @commando-modules npm organization
- Publish first official module (@commando-modules/aws)
- Module authoring guide
- Module submission process
- Automated security scanning (CI)
- Dependency audit in CI
- Lock file verification
- SBOM generation
# Initial setup
git clone https://github.com/jdillon/commando ~/.commando
cd ~/.commando
bun install # Installs commando core deps
# Add modules
cmdo module add aws
cmdo module add kubernetes
# Use in project
cd ~/my-project
cmdo aws:sync my-bucket
cmdo k8s:deploy staging
# Update modules (monthly)
cmdo module outdated
cmdo module audit
cmdo module update
# Everything safe and up to date! ✓# Create module
mkdir commando-module-aws
cd commando-module-aws
cat > package.json <<EOF
{
"name": "@commando-modules/aws",
"version": "1.0.0",
"main": "module.ts",
"keywords": ["commando", "commando-module", "aws"]
}
EOF
cat > module.ts <<EOF
export default {
commands: {
'aws:sync': { ... }
}
};
EOF
# Publish
bun publish
# Users can now:
# cmdo module add aws| Aspect | Bash + Git Modules | Bun + npm Modules |
|---|---|---|
| Install | git clone ... |
cmdo module add aws |
| Update | Manual git pull |
cmdo module update |
| Versions | Git SHAs | Semantic versions |
| Dependencies | None | Automatic |
| Security | Manual review | cmdo module audit |
| Private modules | SSH complexity | npm registry |
| Discovery | README lists | cmdo module search |
Bun's package manager turns modules into a first-class feature.
This is actually better than most plugin systems (including Bash, Vim, etc.)!