| name | bun-typescript-development |
| description | TypeScript development with Bun using TDD, single-function modules, barrel exports, and collocated tests |
| license | MIT |
| compatibility | opencode |
| metadata | {"category":"development","runtime":"bun","language":"typescript"} |
Bun and TypeScript Development Standards
This skill guides TypeScript development using Bun as the exclusive runtime and package manager.
Core Principles
Use Bun exclusively - No Node.js, npm, yarn, or pnpm
TypeScript only - No JavaScript (except Nx generators)
Strict mode enabled - All code compiles with strict: true
1 function per module MAX - Each module exports exactly one primary function
Always arrow functions - Use arrow functions instead of named functions or classes
Barrel modules - Use index.ts for public API re-exports
Test collocation - Tests next to implementation as .test.ts
Explicit types - No any, explicit return types required
Module System Strategy
- Root workspace: CommonJS (no
"type": "module" in root package.json)
- Apps & Packages: ESM (
"type": "module" in package.json)
- Nx Executors/Generators: CommonJS (Nx convention in
tools/)
- Test Files: Bun tests use ESM, Jest uses CommonJS
Bun Commands
bun install
bun add <package>
bun add -D <dev-package>
bun remove <package>
bun run src/index.ts
bun --watch src/index.ts
bun test
bun run build
bunx nx build <package>
bunx nx build <package> --watch
TypeScript Configuration
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "node",
"declaration": true,
"sourceMap": true,
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"resolveJsonModule": true
}
}
Code Organization
One Function Per Module MAX
export const validateName = (name: string): boolean => {
return /^[a-z][a-z0-9-]*$/.test(name);
};
export function validateName(name: string): boolean {
return /^[a-z][a-z0-9-]*$/.test(name);
}
Barrel Modules
export { validateName } from "./validate-name";
export { formatError } from "./format-error";
import { validateName } from "./utils";
Unit Test Collocation
Tests must be colocated with implementation files as .test.ts:
import { describe, it, expect } from "bun:test";
import { validateName } from "./validate-name";
describe("validateName", () => {
it("should validate names", () => {
expect(validateName("my-plugin")).toBe(true);
});
});
Linting with Biome
bun run lint
bun run lint:affected
bun run format
bun run format:check
bun run validate:tsdoc
biome check --write .
biome format --write .
biome check src/utils/validate.ts
biome explain noUnusedVariables
biome rage
Biome configuration in biome.json:
- Line width: 120
- Indent width: 2
- Complexity rules enabled
- TSDoc validation integrated
Bun Features
Shell
import { $ } from "bun";
const output = await $`ls -la`.text();
File I/O
const file = Bun.file("package.json");
const json = await file.json();
await Bun.write("output.txt", "content");
Build Setup
{
"name": "@scope/package",
"main": "dist/index.cjs",
"module": "dist/index.js",
"types": "dist/index.d.ts",
"files": ["dist"],
"scripts": {
"build": "bunx tsup src/index.ts --format esm,cjs --dts --out-dir dist",
"test": "bun test",
"dev": "bunx tsup src/index.ts --format esm,cjs --dts --out-dir dist --watch"
}
}
Troubleshooting
bun upgrade
rm -rf ~/.bun/install/cache
rm -rf node_modules bun.lockb && bun install
bunx tsc --showConfig
bunx tsc --noEmit
rm -rf dist && bun run build
bunx nx reset
bunx nx reset && rm -rf node_modules bun.lockb && bun install
File Naming
src/index.ts
src/utils/validate-name.ts
src/utils/validate-name.test.ts
src/index.js
src/Plugin.ts
src/utils/helpers.ts
Type Patterns
export type Validator = (value: unknown) => boolean;
export type Status = "pending" | "success" | "error";
export interface Config {
name: string;
version: string;
}