Contributing to helpers4
Contributing to helpers4
Section titled “Contributing to helpers4”Thank you for your interest in contributing! This guide explains everything you need to know to create high-quality helpers for this project.
Prerequisites
Section titled “Prerequisites”- Node.js >= 20.0.0 (24 LTS recommended)
- pnpm (enabled via corepack:
corepack enable) - Git with conventional commits
Project structure
Section titled “Project structure”Categories: array, commit, date, function, id, number, object, observable, promise, string, type, url, version.
Creating a new helper
Section titled “Creating a new helper”Step 1 — Implementation
Section titled “Step 1 — Implementation”Create helpers/<category>/functionName.ts:
Rules:
- License header is required on every source file (see above)
anyis forbidden — useunknown, generics, or specific types- JSDoc is required with
@param,@returns,@example, and@since - One function per file — keep it focused and tree-shakable
- No side effects — pure functions only
- Use
readonlyarrays in parameters when the function does not mutate - 2-space indentation, single quotes
- Always use
@since next— the real version is injected automatically at stable release time (prerelease builds keepnextso the tag retains its semantic meaning). Never hard-code a version number like@since 2.0.0— the tag will be wrong the moment the release number changes.
Step 2 — Tests
Section titled “Step 2 — Tests”Create helpers/<category>/functionName.test.ts:
Coverage requirement: 100% on lines, functions, branches, and statements — no exceptions.
What to test:
- Normal/happy path with different data types
- Empty inputs
- Edge cases (all match, none match, single element)
- Boundary values
- Type coercion traps (e.g.
0,false,'',null) - Callback arguments (value, index, etc.)
Run tests:
Step 2b — Property-based & contract tests
Section titled “Step 2b — Property-based & contract tests”Create helpers/<category>/functionName.spec.ts alongside the unit test file:
Two types of tests live in .spec.ts:
- Property-based tests (using
fast-check) — verify invariants that hold for any input, using randomly generated data. Think of them as “for all inputs, this property must hold”. - Contract/boundary tests — explicit tests on adversarial or boundary inputs (empty strings,
null,undefined,Infinity,NaN, path traversal sequences, scheme abuse…) that document the function’s behavior at its limits.
Guidelines:
- Use
fc.assert(fc.property(...))for property-based tests - Group them under
describe('functionName — property-based')anddescribe('functionName — contract') - Contract tests are especially important for
string/*,url/*, andversion/* .spec.tsfiles are excluded from coverage measurement — they test properties, not code branches
Run spec files:
Step 3 — Examples
Section titled “Step 3 — Examples”Create helpers/<category>/functionName.example.ts:
Examples serve two purposes:
- Smoke tests — the
assertfunctions are executed to validate behavior - Documentation —
title,description, andcodeare rendered on the website
Run examples: pnpm examples
Step 4 — Export
Section titled “Step 4 — Export”You do not need to manually edit helpers/<category>/index.ts.
That file is auto-generated during the build and ignored by Git.
To make your helper available, simply add your implementation as
helpers/<category>/functionName.ts — the build will discover it and
generate the category re-exports automatically.
Step 5 — Benchmark (optional)
Section titled “Step 5 — Benchmark (optional)”Create helpers/<category>/functionName.bench.ts for performance-sensitive helpers:
Run benchmarks:
Benchmarks are non-blocking and opt-in — they don’t fail the CI and are not required for every helper. Add a bench file when the function is on a hot path (tight loops, string manipulation on large inputs, frequent array traversals). Simple one-liners, type guards, and thin wrappers do not need benchmarks.
Quality checks
Section titled “Quality checks”Before submitting, run:
Intentional cross-category duplicates
Section titled “Intentional cross-category duplicates”Some helpers exist in both array/ and object/ on purpose — do not try to deduplicate them:
| Helper | array/ | object/ |
|---|---|---|
compact | removes falsy items from an array | removes falsy values from an object |
equalsShallow | positional === comparison | keys + === value comparison |
Why? Each category is published as its own npm package (@helpers4/array, @helpers4/object). A user who imports only @helpers4/array must not pull in object/ code — tree-shaking across packages requires the duplication to be explicit.
Commit messages
Section titled “Commit messages”Follow Conventional Commits with a gitmoji between the scope and the description.
Format: <type>(<scope>): <emoji> <description>
Scopes: array, commit, date, function, id, number, object, observable, promise, string, type, url, version, CI-CD
| Type | Primary | Alternatives (gitmoji.dev) | When to use |
|---|---|---|---|
| feat | ✨ | 🚸 UX, ♿️ a11y, 🌐 i18n, 💬 text/literals | New feature |
| fix | 🐛 | 🚑️ hotfix, 🔒️ security, 🩹 trivial, 🥅 errors, 🚨 warnings, ✏️ typo | Bug fix |
| docs | 📝 | 💡 source comments, 📄 license | Documentation |
| refactor | ♻️ | 🎨 structure, 🔥 remove code, ⚰️ dead code, 🚚 move/rename | Code refactoring |
| test | ✅ | 🧪 failing test, 💚 fix CI test | Tests |
| chore | 🔧 | 🙈 gitignore, 🔖 tag/release, 📌 pin deps, 🩺 healthcheck | Maintenance |
| perf | ⚡️ | — | Performance |
| style | 💄 | 🎨 code style | Code style / UI |
| ci | 👷 | 💚 fix CI | CI/CD |
| build | 📦️ | ➕ add dep, ➖ remove dep, ⬆️ upgrade dep, ⬇️ downgrade dep | Build system |
| revert | ⏪️ | — | Revert |
Pick the most specific gitmoji that matches the change. The primary is the safe default; reach for an alternative when it adds real signal. Full list: https://gitmoji.dev
Examples:
Checklist
Section titled “Checklist”Before opening a PR, make sure:
- One function per file, in the correct category
- License header present on all new files
- JSDoc with
@param,@returns,@example,@since next - No
any— useunknownor specific types- Tests with 100% coverage (lines, functions, branches, statements)
- Property-based + contract spec file (
functionName.spec.ts)
- Example file with at least 2 examples and
assertfunctions -
pnpm testpasses -
pnpm typecheckpasses -
pnpm lintpasses - Commits follow conventional commit format
Adding a new category
Section titled “Adding a new category”If your helper doesn’t fit any existing category:
- Create
helpers/<new-category>/ - Add a
config.json: - The build will auto-generate
index.tsfor the new category - Add the scope to the commit convention
For AI contributors
Section titled “For AI contributors”If you are an AI coding agent contributing to this repo:
- Read
AGENTS.mdat the root for full conventions and restrictions - Never use
any— the project enforces strict typing - All code, comments, commits, and documentation must be in English
- Follow the exact file structure shown above
- Do not push directly — the maintainer will review and push
- Check
docs/native-alternatives.jsonbefore creating a helper that duplicates a native API
Getting help
Section titled “Getting help”- Open an issue for questions
- Check
.copilot/GAPS.mdfor a list of helpers we’d like to add - Look at existing helpers as reference implementations
License
Section titled “License”By contributing, you agree that your contributions will be licensed under the LGPL-3.0-or-later license.