Contributing
Getting started
Section titled “Getting started”git clone https://github.com/pedrotroccoli/1o1-utils.gitcd 1o1-utilspnpm installAvailable scripts
Section titled “Available scripts”| Command | Description |
|---|---|
pnpm test | Run tests |
pnpm test:coverage | Run tests with coverage report |
pnpm build | Compile TypeScript |
pnpm check | Lint + format check (Biome) |
pnpm check:fix | Lint + format auto-fix |
pnpm bench | Run all benchmarks |
pnpm size | Check bundle sizes |
Adding a new utility
Section titled “Adding a new utility”1. Create the folder
Section titled “1. Create the folder”src/<category>/<util-name>/Categories: arrays, async, browser, comparisons, formatters, functions, numbers, objects, strings, validators. Use kebab-case for the folder name.
2. Create the files
Section titled “2. Create the files”Every utility has exactly 4 files:
types.ts — Type definitions
interface MyUtilParams { // named parameters}
type MyUtilResult = // return type
type MyUtil = (params: MyUtilParams) => MyUtilResult;
export type { MyUtil, MyUtilParams, MyUtilResult };index.ts — Implementation
import type { MyUtilParams, MyUtilResult } from "./types.js";
/** * Brief description of what this utility does. * * @keywords common term 1, common term 2, common term 3 * @see RFC/Standard reference if applicable (https://...) */function myUtil({ param1, param2 }: MyUtilParams): MyUtilResult { // validate inputs // implementation}
export { myUtil };index.spec.ts — Tests (Mocha + Chai)
import { expect } from "chai";import { describe, it } from "mocha";import { myUtil } from "./index.js";
describe("myUtil", () => { it("should do the expected thing", () => { const result = myUtil({ param1: "value" }); expect(result).to.deep.equal(/* expected */); });});index.bench.ts — Benchmarks (tinybench)
import { Bench } from "tinybench";import { getDatasets } from "../../benchmarks/helpers.js";import { myUtil } from "./index.js";
const bench = new Bench({ name: "myUtil", time: 1000 });
for (const { name, data: getData } of getDatasets()) { const data = getData(); bench .add(`1o1-utils (${name})`, () => { myUtil({ /* ... */ }); }) .add(`lodash (${name})`, () => { /* lodash equivalent */ });}
export { bench };3. Register the utility
Section titled “3. Register the utility”Add the export to src/index.ts:
export { myUtil } from "./<category>/my-util/index.js";Add the export entry to package.json:
"./my-util": { "import": "./dist/<category>/my-util/index.js", "types": "./dist/<category>/my-util/index.d.ts"}Add a size-limit entry to .size-limit.json:
{ "name": "my-util", "path": "dist/<category>/my-util/index.js", "limit": "1 kB"}4. Update llms.txt and llms-full.txt
Section titled “4. Update llms.txt and llms-full.txt”Add the new utility to both files at the root of the repository:
llms.txt— add a link entry under the appropriate category sectionllms-full.txt— add a full documentation block with signature, parameters, return type, example, and edge cases
These files are served on the docs site for AI tool discoverability.
5. Create a changeset
Section titled “5. Create a changeset”pnpm changesetChoose minor for new utilities, patch for bug fixes.
Code conventions
Section titled “Code conventions”- Named object parameters — all functions take a single object, never positional args. Exception: function composition utilities (
pipe,once) may use positional/variadic args when it’s the idiomatic pattern. - Type naming —
<Name>Params,<Name>Result,<Name>(function type) - No external dependencies — use only TypeScript/JS builtins
- Import extensions — always use
.jsin import paths (required for ESM) - Input validation — validate parameters and throw descriptive errors. Exception: checker functions (
isNil,isCircular,isEmpty) returnfalseinstead of throwing;safelyreturns a[error, result]tuple;getreturnsundefinedor a default value. - Named exports only — no default exports
- Immutability — all array/object utils must return new instances, never mutate inputs
Naming conventions
Section titled “Naming conventions”| Pattern | Convention | Example |
|---|---|---|
| Boolean checks | isX | isNil, isEmpty, isCircular |
| Validators | isValidX | isValidUrl, isValidEmail |
| Conversions | toX | toNumber |
| Formatters | formatX | formatSeconds |
| Generators | generateX | generateString |
| Normalizers | normalizeX | normalizeEmail |
| No type suffix | Don’t add the type to the name | clamp not clampNumber |
Discoverability (mandatory)
Section titled “Discoverability (mandatory)”Every utility must include:
-
@keywordsin JSDoc — common-language terms developers might search for:/*** Clamps a number between a minimum and maximum bound.** @keywords limit number, restrict range, min max, bound*/ -
@seein JSDoc — RFC or standard reference, if the util aligns with one:/*** @see RFC 5321 — SMTP (https://datatracker.ietf.org/doc/html/rfc5321)*/ -
“Also known as” on the docs page — alternative names for the same concept:
Also known as: limit number, restrict range, min/max bound
-
“Prompt suggestion” on the docs page — a ready-to-copy prompt for AI assistants. Use a fenced
textcode block (renders a copy button) and always prefix with the canonical references so the LLM can look up the real API:## Prompt suggestion```textI'm using 1o1-utils (npm: https://www.npmjs.com/package/1o1-utils, GitHub: https://github.com/pedrotroccoli/1o1-utils, LLM context: https://pedrotroccoli.github.io/1o1-utils/llms.txt). Show me how to use clamp to restrict a slider value between min and max```
Style (enforced by Biome)
Section titled “Style (enforced by Biome)”- 2-space indentation
- Double quotes
- Semicolons always
- Trailing commas
Run pnpm check:fix before committing.
Testing
Section titled “Testing”- Framework: Mocha + Chai
- Coverage: c8 with 80% minimum on lines, branches, functions, and statements
- Cover happy paths, edge cases, and error cases
Bundle size
Section titled “Bundle size”Each utility must stay under its size limit (1-2 kB gzipped). The total library limit is 5 kB gzipped. Run pnpm size to verify.
Pull request checklist
Section titled “Pull request checklist”- All 4 files created (
index.ts,types.ts,index.spec.ts,index.bench.ts) - Export added to
src/index.ts - Export entry added to
package.json - Size-limit entry added to
.size-limit.json - Utility added to
llms.txtandllms-full.txt -
@keywordsadded to JSDoc -
@seeRFC/standard reference added (if applicable) - “Also known as” section added to docs page
- “Prompt suggestion” section added to docs page
-
pnpm checkpasses -
pnpm testpasses with >80% coverage -
pnpm build && pnpm sizepasses - Changeset created