From harness-engineering
TypeScript/JavaScript harness configuration guidance. Covers Biome (format), Oxlint (lint), tsc (type check), dependency-cruiser or @softarc/sheriff (architecture boundaries), and Knip (dead code). Use when setting up TS harness, troubleshooting TS lint hook failures, choosing between ESLint and Oxlint, or enforcing layer boundaries in TS monorepos. Do NOT use for Go or Proto — see go-stack / proto-stack.
How this skill is triggered — by the user, by Claude, or both
Slash command
/harness-engineering:ts-stackThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
The TS side of the harness. Fast, Rust-based tooling so PostToolUse hooks finish in under a second.
The TS side of the harness. Fast, Rust-based tooling so PostToolUse hooks finish in under a second.
| Role | Tool | Why |
|---|---|---|
| Format | Biome | Rust, ~50x faster than Prettier, same config for JS/TS/JSON/JSX |
| Lint | Oxlint | Rust, 50–100x faster than ESLint, covers ~400 common ESLint rules |
| Type check | tsc --noEmit | Still the only source of truth for types |
| Architecture | dependency-cruiser or @softarc/sheriff | Layer boundary enforcement |
| Dead code | Knip | Finds unused exports/files/deps (Vercel deleted 300k LOC with it) |
ESLint is fine but Node-based — PostToolUse hooks need to finish in <1s to feel responsive. Oxlint covers the common rules. If you need rules Oxlint doesn't have, run ESLint in CI, not in the hook.
Pick one. Don't run both.
Use ${CLAUDE_PLUGIN_ROOT}/templates/biome.json as the starting point. It has:
noExplicitAny as error in strict modeClean architecture boundaries for a typical Node.js backend:
src/
├── domain/ # No imports from anything below
├── application/ # May import domain
├── infrastructure/ # May import domain + application
└── interfaces/ # May import everything below
dependency-cruiser config enforcing this:
// .dependency-cruiser.js (NOTE: protected by pre-config-protect hook)
module.exports = {
forbidden: [
{
name: 'domain-no-outside',
severity: 'error',
from: { path: '^src/domain' },
to: { path: '^src/(application|infrastructure|interfaces)' },
},
{
name: 'application-no-infrastructure',
severity: 'error',
from: { path: '^src/application' },
to: { path: '^src/infrastructure' },
},
],
};
When you Write/Edit a .ts/.tsx file, post-edit-lint.js runs:
biome format --write <file> (silent auto-fix)oxlint --fix <file> (silent auto-fix)oxlint <file> (collect remaining violations)additionalContexttsc is NOT run in the hook (too slow for per-file). It's in lefthook pre-commit and CI.
tsconfig.json has trailing commas, Biome will format them out. Usually fine — tsc accepts both..eslintrc: configure via .oxlintrc.json or biome.json (Biome's lint side is compatible).edit-lint-feedback-loop — how PostToolUse hooks work end-to-endarchitecture-enforcement — dependency-cruiser deep diveharness-setup — bootstrap workflowSee gotchas.md.
Provides UI/UX resources: 50+ styles, color palettes, font pairings, guidelines, charts for web/mobile across React, Next.js, Vue, Svelte, Tailwind, React Native, Flutter. Aids planning, building, reviewing interfaces.
Searches MemPalace before answering questions about past work, people, projects, or prior decisions. Returns verbatim stored content instead of guessing from model memory.
npx claudepluginhub toru-oizumi/claude-harness-engineering --plugin harness-engineering