This document describes how the Idle Champions Code Redeemer Bot manages dependencies using standardized tooling and practices to ensure reproducible, secure builds.
This documentation is published with all releases to ensure users understand how dependencies are selected, obtained, and tracked. [OSPS-DO-06.01]
The project uses standardized tooling for the Node.js/Bun ecosystem to manage all dependencies:
- Package Manager: Bun (standardized for this ecosystem)
- Dependency Manifest:
package.json(standard Node.js format) - Lock File:
bun.lock(ensures reproducible builds) - Task Runner: Mise (orchestrates standardized tasks)
- Dependency Verification: Bun audit for vulnerability scanning
When introducing a new dependency, the following criteria are evaluated:
- ✅ Solves a real problem or reduces complexity
- ✅ No existing solution in the codebase or standard library
- ❌ Not added for convenience if maintainability cost is high
- ❌ Not added "just in case" without a use case
- ✅ Production-ready (v1.0.0 or higher)
- ✅ Active maintenance (recent commits within 3-6 months)
- ✅ Reasonable version history (not v0.x unless necessary)
- ✅ Used by other projects in the ecosystem
- ❌ Not beta/alpha versions unless unavoidable
- ❌ Not abandoned projects
- ✅ No known vulnerabilities (
bun auditpasses) - ✅ Clear security policy and vulnerability disclosure process
- ✅ Regular dependency updates
- ✅ Maintained by reputable maintainers
- ❌ Not packages with history of security issues
- ❌ Not packages from unknown sources
- ✅ Well-documented with clear examples
- ✅ TypeScript support (native or via @types/*)
- ✅ Good test coverage
- ✅ Clear API design
- ✅ Active community (issues answered, PRs reviewed)
- ❌ Not packages with poor documentation
- ❌ Not unmaintained forks
- ✅ Reasonable bundle size
- ✅ No unnecessary transitive dependencies
- ✅ Compatible with Bun runtime
- ❌ Not bloated when lighter alternatives exist
- ❌ Not packages that conflict with our tech stack
- ✅ Permissive licenses (MIT, Apache 2.0, BSD, ISC)
- ✅ Compatible with project license (ISC)
- ✅ No GPL/AGPL for production code
- ✅ Clear license headers in package
- ❌ Not unclear or proprietary licenses
| Package | Version | Purpose | Selection Notes |
|---|---|---|---|
| discord.js | 14.26.4 | Discord bot framework | Standard, active, well-maintained |
| drizzle-orm | 0.45.2 | Type-safe ORM for SQLite | Zero-query overhead, TS-first |
| winston | 3.19.0 | Logging framework | Structured logging, rotation |
Note:
dotenv,node-fetch, andsqlite3were removed. Bun loads.envnatively, provides a built-in Fetch API, and includesbun:sqliteas a first-party module.
| Package | Purpose | Rationale |
|---|---|---|
| @typescript-eslint/ | Code quality | Mandatory for TypeScript linting |
| eslint | Linting | Code consistency |
| prettier | Formatting | Code style consistency |
| typescript | Type-check only | noEmit: true; Bun runs TS natively |
| @types/bun | Bun type definitions | Required for bun:sqlite types |
| drizzle-kit | Schema management | Generate SQL migrations from TS schema |
| husky | Git hooks | Mandatory for pre-commit checks |
| commitlint | Commit validation | Enforce Conventional Commits |
| lint-staged | Pre-commit linting | Quality gates |
Process:
- Evaluate against selection criteria above
- Check
bun auditfor vulnerabilities - Test in development locally
- If approved:
bun add package-name # OR for dev dependencies: bun add --development package-name - Commit both
package.jsonandbun.lock - Update CHANGELOG.md with reason for addition
Decision Criteria Checklist:
- Solves a real problem
- Production-ready (v1.0+)
- No known vulnerabilities
- Well-documented
- Active maintenance
- Reasonable size
- Compatible license
- Team consensus
When Dependabot Creates PR:
- Check changelog for breaking changes
- Review vulnerability details (if security update)
- Verify tests pass (CI/CD runs)
- Manual testing if significant changes
- Merge if safe, comment with rationale
Version Update Policy:
- ✅ Patch updates (2.0.0 → 2.0.1): Auto-merge if tests pass
- ✅ Minor updates (2.0.0 → 2.1.0): Review changelog, auto-merge if backward compatible
⚠️ Major updates (2.0.0 → 3.0.0): Manual review required, test thoroughly
Why Bun?
- Official JavaScript/TypeScript package manager for Node.js ecosystem
- 3-4x faster than npm/yarn
- Built-in dependency verification
- Excellent lock file support
- Zero-install capable with proper lock file tracking
Key Commands:
bun install # Install all dependencies
bun install --production # Install only production dependencies
bun update # Update dependencies
bun audit # Security vulnerability scanningStandardized via Mise:
mise run install # Wrapper for: bun install
mise run prod:install # Production-only: bun install --production --frozen-lockfile
mise run audit # Wrapper for: bun audit
mise run update # Wrapper for: bun updatePurpose: Declares all project dependencies and their versions.
Location: package.json (root)
Structure:
{
"dependencies": {
"discord.js": "14.26.4",
"drizzle-orm": "0.45.2",
"winston": "3.19.0"
},
"devDependencies": {
"@types/bun": "1.3.14",
"@typescript-eslint/eslint-plugin": "8.59.2",
"drizzle-kit": "0.31.10",
"eslint": "10.3.0",
"prettier": "3.8.3"
},
"peerDependencies": {
"typescript": "6.0.3"
}
}Key Requirements:
- ✅ All production dependencies explicitly listed
- ✅ All development dependencies explicitly listed
- ✅ Pinned versions (not ranges) for reproducibility
- ✅ Tracked in git for auditability
Purpose: Provides exact reproducible builds by locking all dependency versions (including transitive dependencies).
Location: bun.lock (root)
Key Features:
- Contains exact versions of all dependencies and sub-dependencies
- Guarantees bit-for-bit identical installs across environments
- Enables offline installation (when combined with proper cache)
- Eliminates "works on my machine" dependency issues
Tracking in Git: ✅ bun.lock is tracked in git (NOT in .gitignore)
- Ensures all developers and CI/CD systems use identical dependency versions
- Makes builds reproducible across machines and time
- Enables quick issue diagnosis (exact version of every package known)
Lock File Workflow:
# After modifying package.json:
bun install # Updates bun.lock with new dependency tree
# To commit changes:
git add package.json bun.lock
git commit -m "chore(deps): update dependency versions"Setup:
cd /path/to/idle-code-redeemer
mise run install # Installs from package.json + bun.lockProcess:
- Mise reads
.mise.tomland installs configured tools (Bun, Node.js) mise run installexecutes:bun install- Bun reads
bun.lockfor exact versions - Creates
node_modules/with locked versions - All developers have identical dependencies
Builder Stage (Dockerfile lines 1-45):
# Copy dependency files
COPY package.json ./
COPY bun.lock ./
# Install all dependencies (for building)
RUN bin/mise run installProduction Stage (Dockerfile lines 46-80):
# Copy dependency files
COPY --from=builder /app/package.json ./
COPY --from=builder /app/bun.lock ./
# Install only production dependencies (frozen)
RUN bin/mise run prod:install
# Equivalent to: bun install --production --frozen-lockfile --ignore-scriptsGuarantees:
- ✅ Builder stage installs all dependencies (including dev) for TypeScript compilation
- ✅ Production stage installs only runtime dependencies
- ✅
--frozen-lockfileensures no dependency changes mid-build - ✅ Identical dependencies across all Docker builds
Dependency Verification Workflow (.github/workflows/dependency-check.yml):
steps:
- uses: actions/checkout@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v1
with:
bun-version: latest
- name: Install dependencies
run: bun install --frozen-lockfile
- name: Vulnerability scan
run: bun audit
- name: Check lock file
run: |
if [[ -n $(git status -s) ]]; then
echo "❌ Lock file mismatch! Run: bun install"
exit 1
fiProcess:
- Checkout code with package.json and bun.lock
- Install Bun runtime
- Run
bun install --frozen-lockfile(fails if versions don't match) - Run
bun auditfor known vulnerabilities - Verify lock file wasn't modified (no hidden changes)
Step 1: Review Dependencies
# Check for outdated dependencies
bun outdated
# Check for security vulnerabilities
bun auditStep 2: Update Specific Dependencies
# Update a single dependency
bun update discord.js
# Update all dependencies
bun update
# Update to latest (be careful with major versions!)
bun update --latestStep 3: Test Thoroughly
# Run full test suite
mise run build # Build TypeScript
mise run lint # Check code quality
mise run dev # Manual testingStep 4: Commit Changes
git add package.json bun.lock
git commit -m "chore(deps): update dependencies for [reason]"Dependabot integration (GitHub):
- Automatically scans for outdated dependencies weekly
- Creates pull requests with updated package.json
- CI/CD automatically tests before merge
- Updates are tracked in CHANGELOG.md
Never:
- ❌ Run
bun installand commit withoutbun.lock - ❌ Use wildcards in version numbers (use pinned versions)
- ❌ Manually edit
bun.lock - ❌ Use
--ignore-scriptsin production installs (except explicitly needed)
# After any dependency changes
bun install --frozen-lockfile
# This will error if package.json and bun.lock are out of sync# Build Docker image with frozen lock file
docker build .
# The build will fail if dependencies can't be installed from lockAll GitHub Actions workflows verify:
- ✅ Lock file matches package.json
- ✅ No vulnerable dependencies
- ✅ Reproducible builds
| Aspect | package.json | bun.lock |
|---|---|---|
| Purpose | Declares dependencies | Locks exact versions |
| Edited by | Developers manually | Bun automatically |
| Tracked in Git | ✅ Yes | ✅ Yes |
| Human readable | ✅ Yes | ❌ No (binary-like format) |
| Scope | Direct dependencies | All dependencies + transitive |
| Use case | Specification | Reproducibility |
Step 1: Add to package.json
bun add package-name
# OR for dev dependencies:
bun add --development package-nameStep 2: Verify bun.lock updated
git status
# Should show:
# modified: package.json
# modified: bun.lockStep 3: Review and commit
git diff package.json # Review version added
git add package.json bun.lock
git commit -m "feat: add new dependency [package-name]"Images published to GitHub Container Registry (GHCR):
ghcr.io/bigmichi1/idle-code-redeemer-bot:2.0.0
Each image includes:
- ✅ Frozen dependency set from bun.lock
- ✅ Only production dependencies
- ✅ No development tools or source code
- ✅ Exact reproducible runtime environment
-
Automated Scanning:
bun auditruns on every push- GitHub Dependabot scans weekly
- TruffleHog checks for leaked credentials
-
Vulnerability Response:
- Critical/High: Update immediately
- Medium: Update within 1 week
- Low: Update within 1 month
- All updates tracked in CHANGELOG.md
-
Lock File Security:
- Pinned versions prevent unexpected updates
- Hash validation ensures downloaded packages match
- Reproducible builds detect package tampering
- ✅ All dependencies pinned to specific versions
- ✅ Lock file prevents silent updates
- ✅ CI/CD validates every build with frozen lock
- ✅ Dependency audit trail in git history
- ✅ Pre-commit hooks prevent secrets in dependencies
Every dependency change is tracked in git:
# View dependency change history
git log --oneline -- package.json bun.lock
# See what dependencies changed in a commit
git show package.json bun.lock < commit-sha > --
# Diff dependencies between versions
git diff v2.0.0 v2.1.0 -- package.jsonTracked Information:
- ✅ When dependencies were added/updated
- ✅ Who made the change (git commit author)
- ✅ Why the change was made (commit message)
- ✅ What exact versions were installed
- ✅ All transitive dependencies (in bun.lock)
Dependency changes are documented in the release changelog:
## [2.1.0] - 2026-05-15
### Changed
- Update discord.js from 14.26.4 to 14.27.0 for bug fixes
### Security
- Update dependencies: sqlite3 6.0.1 → 6.0.2 (security patch)Benefits:
- ✅ Human-readable description of dependency changes
- ✅ Security implications documented
- ✅ Explains why dependencies were updated
- ✅ Published with release on GitHub
bun.lock is the authoritative source for exact versions:
# View exact locked versions
cat bun.lock | head -50
# Verify production dependencies
bun ls --production
# Audit locked dependencies
bun auditInformation in bun.lock:
- ✅ Exact version of every package
- ✅ Hashes for integrity verification
- ✅ All transitive dependencies
- ✅ Resolution for conflicts
- ✅ Build metadata
Dependabot Integration:
- Scans npm registry weekly
- Detects outdated packages
- Creates pull requests for updates
- Tracks vulnerability advisories
GitHub's Dependency Graph:
- Automatically analyzes package.json
- Shows dependency tree visualization
- Detects vulnerable packages
- Available at:
/network/dependencies
bun audit Output:
$ bun audit
Audited 215 packages
0 vulnerabilities foundWhen a release is created, dependency information is published:
-
GitHub Release Notes
- Link to CHANGELOG.md with dependency changes
- Signature verification available
-
Docker Image Metadata
- Lists dependency versions installed
- Verification available via
docker inspect
-
This Documentation
- Published alongside release
- Contains selection criteria
- Explains tracking strategy
Example Release Notes:
## Dependencies
For details on how dependencies are selected, obtained, and tracked, see:
- [Dependency Management Documentation](docs/dependency-management.md)
- [CHANGELOG.md](CHANGELOG.md) - Updated dependencies section
- [Security Policy](SECURITY.md) - Dependency vulnerability handling
All dependencies are locked in bun.lock for reproducible builds.
Current production dependencies: 5
Current development dependencies: 12
All pass security audit (bun audit).[tasks.install]
description = "Install dependencies with Bun"
run = "bun install"
[tasks."prod:install"]
description = "Install production dependencies only"
run = "bun install --production --frozen-lockfile --ignore-scripts"
[tasks.audit]
description = "Audit dependencies for vulnerabilities"
run = "bun audit"
[tasks.update]
description = "Update all dependencies"
run = "bun update"Lock files excluded from linting:
// .eslintignore
bun.lock;
package - lock.json;
yarn.lock;# ✅ Track bun.lock for reproducible builds
# bun.lock (NOT ignored)
# ✅ Ignore generated node_modules
node_modules/
# ✅ Ignore lockfiles from other package managers
package-lock.json
yarn.lock