What's the problem?
This monorepo runs exclusively on Bun, but agents (Claude Code, Codex, etc.) consistently reach for node-fs / hand-rolled patterns when a native Bun API would be cleaner and idiomatic for this codebase. Recent examples from PR review:
The pattern: agents default to the Node API surface from their training data and miss Bun-specific affordances even when they make the code materially shorter and more idiomatic.
Proposed solution
Add an agent-loaded skill or .contextbridge/rules/ file (similar to the existing error-handling-neverthrow.md and testing-patterns.md) that:
- States the project is Bun-first — agents should reach for
Bun.* globals before equivalent Node APIs.
- Lists the high-value cases with before/after pairs. Initial set:
Bun.Glob for file-pattern matching (vs. manual readdirSync walking)
Bun.file(path).text() for reading text (vs. readFileSync)
Bun.spawn / Bun.spawnSync (vs. child_process.spawn)
Bun.serve for HTTP (already used in packages/server)
bun:test runner (vs. importing third-party test libraries)
- Bun macros for compile-time evaluation in build/codegen paths
- Calls out scope — application code that ships to consumers running under non-Bun runtimes shouldn't depend on
Bun.* globals. CLI/build/script code can. Today the only externally-facing runtime is the compiled contextbridge binary, which IS Bun, so this restriction is mostly theoretical for the moment.
- Hooks into the existing rule auto-load —
.claude/rules/*.md is already auto-loaded by Claude Code when editing files in this repo; the new rule should live there (or .contextbridge/rules/ if it should apply to all harnesses).
Alternatives you considered
- ESLint rule — could flag
readdirSync with recursive: true and suggest Bun.Glob. Higher precision but lower coverage; doesn't help with macros, Bun.spawn, etc. where the trigger isn't a single AST shape.
- CLAUDE.md / AGENTS.md note — possible but those files are already dense; a dedicated rule is more discoverable.
- Do nothing — accept that PR review catches these. Works but burns reviewer attention on the same pattern across every PR.
Additional context
Discussion thread: #115 (comment)
blimmer: Great callout! I wonder if we should have some agent skill that guides it to use more native bun solutions (like this, macros in your previous DB PR, etc.)
jcarver989: yea, worth trying!
This is the spinoff issue from that thread.
What's the problem?
This monorepo runs exclusively on Bun, but agents (Claude Code, Codex, etc.) consistently reach for node-fs / hand-rolled patterns when a native Bun API would be cleaner and idiomatic for this codebase. Recent examples from PR review:
handlebars.ts— first draft used a manual recursivewalk()overreaddirSync. Reviewer pointed outreaddirSync({ recursive: true })exists; the final form went one step further tonew Bun.Glob('**/*.md').scanSync(rootDir). The agent only got there via human prompting. See: feat: tell Codex to run contextbridge open outside the sandbox #115 (comment) and feat: tell Codex to run contextbridge open outside the sandbox #115 (comment)The pattern: agents default to the Node API surface from their training data and miss Bun-specific affordances even when they make the code materially shorter and more idiomatic.
Proposed solution
Add an agent-loaded skill or
.contextbridge/rules/file (similar to the existingerror-handling-neverthrow.mdandtesting-patterns.md) that:Bun.*globals before equivalent Node APIs.Bun.Globfor file-pattern matching (vs. manualreaddirSyncwalking)Bun.file(path).text()for reading text (vs.readFileSync)Bun.spawn/Bun.spawnSync(vs.child_process.spawn)Bun.servefor HTTP (already used inpackages/server)bun:testrunner (vs. importing third-party test libraries)Bun.*globals. CLI/build/script code can. Today the only externally-facing runtime is the compiledcontextbridgebinary, which IS Bun, so this restriction is mostly theoretical for the moment..claude/rules/*.mdis already auto-loaded by Claude Code when editing files in this repo; the new rule should live there (or.contextbridge/rules/if it should apply to all harnesses).Alternatives you considered
readdirSyncwithrecursive: trueand suggestBun.Glob. Higher precision but lower coverage; doesn't help with macros,Bun.spawn, etc. where the trigger isn't a single AST shape.Additional context
Discussion thread: #115 (comment)
This is the spinoff issue from that thread.