You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Dec 10, 2025. It is now read-only.
-**Mandatory Co-location:** Test (`*.test.ts`) and benchmark (`*.bench.ts`) files **MUST** reside in the same directory as the source file they target.
32
32
33
33
---
34
34
@@ -45,12 +45,18 @@ pnpm install
45
45
- Each package has its own README with install and usage.
46
46
- See [packages/](./packages/).
47
47
48
-
### Run
48
+
### Run Standard Scripts
49
+
50
+
These scripts should be defined in the root `package.json` and individual package `package.json` files as needed, aligning with Core Instruction V.I.
49
51
50
52
```bash
51
-
pnpm run build # Build packages if needed (e.g., docs site)
52
-
pnpm run check # Run Biome checks (lint + format check) across all packages
53
-
pnpm run format # Apply Biome formatting fixes across all packages
53
+
pnpm run format # Apply Biome formatting fixes
54
+
pnpm run check # Run Biome checks (lint + format check) & apply safe fixes
55
+
pnpm run lint # Alias for 'check'
56
+
pnpm run typecheck # Run TypeScript compiler checks (tsc --noEmit)
57
+
pnpm run test# Run tests (e.g., Vitest)
58
+
pnpm run validate # Run check, typecheck, and test sequentially
59
+
pnpm run build # Build packages using tsup (via Turborepo if applicable)
54
60
```
55
61
56
62
---
@@ -60,69 +66,81 @@ pnpm run format # Apply Biome formatting fixes across all packages
// Add project-specific overrides below if absolutely necessary
81
+
// "files": { "ignore": ["dist/**"] },
82
+
// "linter": { ... },
83
+
// "formatter": { ... }
75
84
}
76
85
```
77
-
*(Note: The relative path `../biome-config/biome.json` works within the monorepo itself, but consuming projects outside the monorepo need the `./node_modules/...` path).*
78
86
79
-
Add scripts to your `package.json`:
80
-
```json
81
-
{
82
-
"scripts": {
83
-
"format": "biome format --write .",
84
-
"check": "biome check --write --unsafe ."
85
-
}
86
-
}
87
-
```
87
+
Add standard scripts to your `package.json` (see "Run Standard Scripts" above).
This section details the recommended project structure for TypeScript NPM packages and outlines key best practices for writing robust, maintainable, and performant code.
8
+
This section details the recommended project structure for TypeScript NPM packages and outlines key best practices for writing robust, maintainable, and performant code, emphasizing the **mandatory co-location** of tests and benchmarks.
9
9
10
-
## 1. Standard NPM Package Structure
10
+
## 1. Standard NPM Package Structure (Co-location MANDATORY)
11
11
12
12
-**Recommended Directory Structure**:
13
13
```
14
14
/
15
-
├── src/ # TypeScript source code
16
-
│ ├── index.ts # Main entry point (exports public API)
17
-
│ ├── types/ # Shared type definitions (e.g., types.ts or interfaces.ts)
-**Co-location Rule (Mandatory):** Test files (`*.test.ts(x)`, `*.spec.ts(x)`) and benchmark files (`*.bench.ts(x)`) **MUST** be located in the **SAME DIRECTORY** as the source file they target. Do **NOT** use separate top-level `test/`, `spec/`, or `bench/` directories. This is enforced by project convention (V.I).
47
41
-**Package Name (`name` in `package.json`)**: Use `kebab-case` (e.g., 'my-awesome-library'). For scoped packages, use `@scope/kebab-case-name`.
48
42
49
43
## 2. Advanced TypeScript Patterns (Encouraged)
50
44
51
45
-**Immutability**:
52
-
- Use `readonly` modifiers for properties and `Readonly<T>` / `ReadonlyArray<T>` (`@typescript-eslint/prefer-readonly`).
46
+
- Use `readonly` modifiers for properties and `Readonly<T>` / `ReadonlyArray<T>`.
53
47
- Leverage TypeScript's `const` assertions (`as const`) for literal types when creating immutable constants.
54
48
-**Type Safety**:
55
-
- Use branded types or nominal typing techniques for primitive type safety where applicable (e.g., distinguishing between different kinds of string IDs).
56
-
- Prefer discriminated unions for modeling state or variants over loose objects or class hierarchies.
49
+
- Use branded types or nominal typing techniques for primitive type safety where applicable.
50
+
- Prefer discriminated unions for modeling state or variants.
57
51
-**Object Creation**:
58
-
- Implement the Builder pattern for complex object creation to ensure valid states.
52
+
- Implement the Builder pattern for complex object creation.
59
53
- Use factory functions or static methods instead of complex constructors.
60
54
-**Operations on Types**:
61
55
- Apply the Visitor pattern for type-safe operations on discriminated unions.
62
-
- Leverage Mapped Types (`Pick`, `Omit`, `Partial`, `Required`, custom) for consistent type transformations.
- Use the `satisfies` operator for ensuring type compatibility without changing the inferred type.
64
58
65
59
## 3. Best Practices
66
60
67
61
-**Error Handling**:
68
-
69
-
- Primarily use discriminated union result types (e.g., `{ success: true, data: T } | { success: false, error: E }`, potentially using helper libraries) for handling predictable errors, making failure an explicit part of the function's contract.
70
-
- Reserve throwing exceptions for truly exceptional, unrecoverable situations (e.g., programming errors, critical infrastructure failures). When throwing, use custom error classes extending `Error`.
71
-
- Always include context and potentially the original error (`cause`) when creating errors or error results.
72
-
- Validate API boundaries and external data rigorously using runtime validation libraries (like Zod, io-ts) that integrate with TypeScript types to ensure data integrity.
62
+
- Primarily use discriminated union result types (e.g., `{ success: true, data: T } | { success: false, error: E }`) for predictable errors.
63
+
- Reserve throwing exceptions for truly exceptional, unrecoverable situations. Use custom error classes extending `Error`.
64
+
- Always include context and potentially the original error (`cause`).
65
+
- Validate API boundaries and external data rigorously using runtime validation libraries (like Zod) that integrate with TypeScript types.
73
66
74
67
-**Asynchronous Code**:
75
-
76
-
- Always prefer `async/await` for readability over raw `Promise.then/catch` chains.
77
-
- Ensure all Promises are handled (use `@typescript-eslint/no-floating-promises` lint rule).
68
+
- Always prefer `async/await` for readability.
69
+
- Ensure all Promises are handled (use Biome lint rules).
78
70
- Use `Promise.all` / `Promise.allSettled` for concurrency.
79
-
- Avoid the `new Promise()` constructor anti-pattern; use `async` functions instead.
80
-
- Implement cancellation patterns (e.g., using `AbortController`) for long-running async operations where appropriate.
71
+
- Avoid the `new Promise()` constructor anti-pattern; use `async` functions.
72
+
- Implement cancellation patterns (e.g., using `AbortController`) where appropriate.
81
73
82
74
-**Performance Optimizations**:
83
75
- Be mindful of object and array allocations within loops or frequently called functions.
84
-
- Use `Set` and `Map` for efficient lookups (O(1) average) compared to array methods like `find` or `includes` (O(n)).
85
-
- Employ lazy initialization for expensive resources or computations.
86
-
- Profile code using Node.js inspector or other tools to identify bottlenecks before optimizing prematurely.
76
+
- Use `Set` and `Map` for efficient lookups.
77
+
- Employ lazy initialization for expensive resources.
78
+
- Profile code using Node.js inspector or other tools before optimizing prematurely.
0 commit comments