# gcanti/fp-ts — codebase unpack

> Canonical page: https://codevetter.com/unpack/fp-ts

This is a deterministic Repo Unpack scan of gcanti/fp-ts — a structural map, not a review, security audit, or maintainer-endorsed description.

- Scanned commit: c0a6472121c67a2b083e62fcff13e7d022e39d8f (2026-04-20)
- Last upstream commit: Fix learning resources link
- Generated by codevetter 1.15.0 on 2026-10-02
- 429 files scanned · 3.9 MB

Source inspection; upstream code and tests were not executed.

## Languages

- TypeScript: 271 files
- Markdown: 140 files
- JSON: 9 files
- YAML: 3 files
- HTML: 1 files
- Sass: 1 files

## Repository structure

- docs/ — 135 files
- src/ — 123 files
- test/ — 81 files
- dtslint/ — 44 files
- perf/ — 15 files
- scripts/ — 6 files
- .github/ — 6 files
- examples/ — 3 files

Probable source entrypoint: `src/` (inferred from the tree, not upstream docs)

## Source layout — src/

- src/Alt.ts — 1 file
- src/Alternative.ts — 1 file
- src/Apply.ts — 1 file
- src/Array.ts — 1 file
- src/Bifunctor.ts — 1 file
- src/BooleanAlgebra.ts — 1 file
- src/BoundedMeetSemilattice.ts — 1 file
- src/Category.ts — 1 file
- src/ChainRec.ts — 1 file
- src/Compactable.ts — 1 file
- src/Const.ts — 1 file
- src/Date.ts — 1 file
- src/EitherT.ts — 1 file
- src/FilterableWithIndex.ts — 1 file

## Package

- package.json: fp-ts v2.16.11 — 24 declared dependencies

## Structural health signals

Average score 7.1/10 across 96 files; 18 hotspots. These are deterministic review leads, not proof of a bug.

## Recent history

- c0a6472121c6 (2026-04-20) Fix learning resources link
- 8e1f04d9116b (2026-04-20) docs: add Getting Started guide with installation instructions (#1968)
- 09045f5819af (2025-08-18) version 2.16.11 (#1964)
- 530394a7a5c1 (2025-08-18) 1962 fix option get ord compare when comparing equality of options (#1963)
- e91bde112e0a (2025-04-18) version 2.16.10 (#1959)

## Overview

fp-ts 2.16.11 is a TypeScript library for developers composing typed functional programs through Option, Either, lazy effects, collections, and algebraic interfaces. Its distinctive architecture uses higher-kinded type dictionaries and explicit instance objects to share combinators across different computational contexts. This brief examines commit c0a6472121c67a2b083e62fcff13e7d022e39d8f through bounded source inspection, including consumer pipelines, asynchronous execution, mutable references, and package assembly; nothing was executed.

## System map

The inspected system is a library whose consumers import functions and instance dictionaries. Its runtime representations use tagged objects, ordinary collections, and functions; higher-kinded types connect these representations at compile time. Package assembly produces two JavaScript module formats and declarations, with special handling for HKT identity. Repository tooling provides linting, runtime tests, type assertions, documentation generation, and publication.
- package.json identifies version 2.16.11 and exposes lib/index.js, es6/index.js, and lib/index.d.ts; it declares sideEffects:false, while the getting-started guide explicitly describes a library without runtime dependencies. — [package.json#L2-L8](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/package.json#L2-L8) [docs/guides/getting-started.md#L24-L28](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/docs/guides/getting-started.md#L24-L28)
- src/index.ts is a namespace barrel importing modules such as Option, Either, IO, TaskEither, and ReaderTaskEither; its exported names include lowercase namespaces and aliases for reserved words. — [src/index.ts#L29-L58](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/index.ts#L29-L58) [src/index.ts#L69-L85](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/index.ts#L69-L85) [src/index.ts#L628-L643](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/index.ts#L628-L643) [src/index.ts#L693-L719](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/index.ts#L693-L719)
- HKT.ts defines HKT through HKT4, open URItoKind dictionaries, URI key unions, and Kind projections; Option and Either register their concrete types through module augmentation. — [src/HKT.ts#L11-L38](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/HKT.ts#L11-L38) [src/HKT.ts#L49-L70](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/HKT.ts#L49-L70) [src/HKT.ts#L80-L126](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/HKT.ts#L80-L126) [src/Option.ts#L235-L247](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/Option.ts#L235-L247)
- Runtime boundaries are explicit: IO<A> is () => A, Task<A> is () => Promise<A>, and TaskEither<E,A> extends Task<Either<E,A>>. — [src/IO.ts#L40-L42](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/IO.ts#L40-L42) [src/Task.ts#L45-L47](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/Task.ts#L45-L47) [src/TaskEither.ts#L70-L77](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/TaskEither.ts#L70-L77)
- ReaderTaskEither receives a caller-supplied environment and returns a TaskEither; State receives state and returns [value,state], while IORef stores a private mutable value in an object. — [src/ReaderTaskEither.ts#L84-L86](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/ReaderTaskEither.ts#L84-L86) [src/State.ts#L24-L26](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/State.ts#L24-L26) [src/IORef.ts#L18-L42](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/IORef.ts#L18-L42)
- npm run build compiles CommonJS and ES modules before executing scripts/build.ts; that script copies package metadata and documentation, generates module manifests, then fixes HKT paths. — [package.json#L15-L18](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/package.json#L15-L18) [tsconfig.build.json#L1-L7](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/tsconfig.build.json#L1-L7) [tsconfig.build-es6.json#L1-L7](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/tsconfig.build-es6.json#L1-L7) [scripts/build.ts#L99-L111](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/scripts/build.ts#L99-L111)
- The configured npm test chain runs ESLint, Prettier, dtslint, Vitest, and docs-ts; GitHub Actions installs dependencies, builds, and runs that chain on Ubuntu with Node 20.12.2. — [package.json#L10-L27](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/package.json#L10-L27) [.github/workflows/main.yml#L12-L28](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/.github/workflows/main.yml#L12-L28)
- Documentation uses docs-ts with src/internal.ts excluded and a Just the Docs site configuration; release executes npm publish from dist, while the root prepublishOnly script deliberately fails. — [docs-ts.json#L1-L3](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/docs-ts.json#L1-L3) [docs/_config.yml#L1-L13](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/docs/_config.yml#L1-L13) [scripts/release.ts#L22-L26](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/scripts/release.ts#L22-L26) [scripts/pre-publish.ts#L1-L6](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/scripts/pre-publish.ts#L1-L6)

## Feature catalog

The user-facing surface consists of TypeScript APIs for representing values, composing computations, and selecting algebraic behavior. The inspected modules cover optionality, typed failures, asynchronous effects, functional collections, explicit environments, state, and accumulated output. Generic algorithms let callers choose execution and combination policies through instances. This catalog groups the examined capabilities and does not claim exhaustive coverage of every exported symbol.
- Option exposes None/Some, nullable conversion, exception-to-None conversion, map/flatMap, pattern matching, and lazy fallback extraction through getOrElse. — [src/Option.ts#L114-L151](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/Option.ts#L114-L151) [src/Option.ts#L336-L337](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/Option.ts#L336-L337) [src/Option.ts#L1008-L1035](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/Option.ts#L1008-L1035) [src/Option.ts#L871-L901](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/Option.ts#L871-L901)
- Either models Left<E>/Right<A>, maps successful values, sequences computations with error unions, and converts synchronous exceptions using a caller-provided onThrow function. — [src/Either.ts#L116-L168](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/Either.ts#L116-L168) [src/Either.ts#L470-L471](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/Either.ts#L470-L471) [src/Either.ts#L1393-L1399](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/Either.ts#L1393-L1399)
- Task and TaskEither support lazy asynchronous computation, parallel or sequential application, indexed traversal, Promise adapters, and acquire/use/release composition. — [src/Task.ts#L109-L138](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/Task.ts#L109-L138) [src/TaskEither.ts#L249-L271](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/TaskEither.ts#L249-L271) [src/TaskEither.ts#L875-L892](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/TaskEither.ts#L875-L892) [src/TaskEither.ts#L1501-L1519](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/TaskEither.ts#L1501-L1519)
- Array and ReadonlyArray provide mapping, flattening, optional lookup/update, sorting by Ord, filterMap, and traversal parameterized by an Applicative. — [src/Array.ts#L1538-L1538](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/Array.ts#L1538-L1538) [src/Array.ts#L1589-L1613](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/Array.ts#L1589-L1613) [src/ReadonlyArray.ts#L848-L851](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/ReadonlyArray.ts#L848-L851) [src/ReadonlyArray.ts#L1763-L1797](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/ReadonlyArray.ts#L1763-L1797)
- ReadonlyMap supports equality-based key lookup and copy-on-change upsert; ReadonlySet builds deduplicated sets and performs union/intersection using a supplied Eq rather than relying only on native identity. — [src/ReadonlyMap.ts#L201-L218](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/ReadonlyMap.ts#L201-L218) [src/ReadonlyMap.ts#L295-L316](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/ReadonlyMap.ts#L295-L316) [src/ReadonlySet.ts#L41-L54](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/ReadonlySet.ts#L41-L54) [src/ReadonlySet.ts#L197-L218](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/ReadonlySet.ts#L197-L218)
- Eq provides custom equality and structural/tuple composition; Ord adds comparison and tuple ordering; Apply.sequenceT and sequenceS collect heterogeneous effects into tuples or records. — [src/Eq.ts#L26-L77](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/Eq.ts#L26-L77) [src/Ord.ts#L27-L54](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/Ord.ts#L27-L54) [src/Apply.ts#L588-L598](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/Apply.ts#L588-L598) [src/Apply.ts#L702-L713](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/Apply.ts#L702-L713)
- ReaderTaskEither combines dependencies with typed asynchronous failures, State exposes get/put/modify and result/state projections, and Writer exposes tell/listen plus Monoid-driven accumulation. — [src/ReaderTaskEither.ts#L586-L595](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/ReaderTaskEither.ts#L586-L595) [src/State.ts#L38-L62](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/State.ts#L38-L62) [src/State.ts#L248-L261](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/State.ts#L248-L261) [src/Writer.ts#L160-L189](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/Writer.ts#L160-L189)
- Additional examined APIs include Tree.make/getEq, These's simultaneous Both case, Json.parse/stringify, and lazy console and Math.random wrappers. — [src/Tree.ts#L43-L83](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/Tree.ts#L43-L83) [src/These.ts#L61-L71](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/These.ts#L61-L71) [src/Json.ts#L37-L67](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/Json.ts#L37-L67) [src/Random.ts#L9-L27](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/Random.ts#L9-L27)

## Data flow

Values enter through constructors, conversion functions, or caller-supplied effect functions. Tagged branches determine whether transformations continue, while instance arguments determine how generic algorithms combine results. Effects execute at explicit function invocation boundaries, and environments or state remain caller-provided values. Persistent file output appears in package tooling; the inspected library state mechanisms operate through tuples or process-local references.
- Option constructors produce {_tag:'Some',value} or the shared None object; Either constructors produce {_tag:'Left',left} or {_tag:'Right',right}, and branch checks inspect _tag. — [src/internal.ts#L15-L40](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/internal.ts#L15-L40) [src/Option.ts#L143-L151](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/Option.ts#L143-L151) [src/Either.ts#L147-L156](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/Either.ts#L147-L156)
- pipe applies transformations to an initial value in order; flow builds a composed function and passes the original arguments and this context to its first function. — [src/function.ts#L294-L341](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/function.ts#L294-L341) [src/function.ts#L651-L689](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/function.ts#L651-L689)
- Json.parse sends a string through JSON.parse inside Either.tryCatch; successful data becomes Right<Json>, and the original thrown value becomes Left<unknown> through identity. — [src/Json.ts#L4-L5](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/Json.ts#L4-L5) [src/Json.ts#L37-L37](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/Json.ts#L37-L37) [src/Either.ts#L1393-L1399](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/Either.ts#L1393-L1399)
- IO.flatMap creates a thunk that invokes ma(), feeds its value to f, then invokes the returned IO; Task.flatMap performs the corresponding sequence through Promise.then. — [src/IO.ts#L78-L86](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/IO.ts#L78-L86) [src/Task.ts#L128-L138](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/Task.ts#L128-L138)
- TaskEither.flatMap delegates to EitherT.flatMap(Task.Monad): the underlying effect resolves first, Left is lifted unchanged, and only Right is passed to the continuation. — [src/TaskEither.ts#L535-L538](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/TaskEither.ts#L535-L538) [src/EitherT.ts#L336-L339](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/EitherT.ts#L336-L339) [src/Task.ts#L128-L138](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/Task.ts#L128-L138)
- ReaderTaskEither's continuation types intersect required environments and union errors; its underlying ReaderTask/ReaderT sequencing supplies the same environment to both computation stages. — [src/ReaderTaskEither.ts#L586-L595](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/ReaderTaskEither.ts#L586-L595) [src/ReaderTask.ts#L153-L156](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/ReaderTask.ts#L153-L156) [src/ReaderT.ts#L153-L156](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/ReaderT.ts#L153-L156)
- State.flatMap threads the returned state into the next function without a hidden store; IORef.write/modify instead update the reference's private field when their IO thunks execute. — [src/State.ts#L100-L110](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/State.ts#L100-L110) [src/State.ts#L248-L261](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/State.ts#L248-L261) [src/IORef.ts#L23-L42](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/IORef.ts#L23-L42)
- Package output flows from package.json through FileSystem.readFile, Json.parse, removal of development metadata, and FileSystem.writeFile; filesystem callback errors become Left through taskify and reach run's error logger/exit code. — [scripts/build.ts#L16-L30](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/scripts/build.ts#L16-L30) [scripts/FileSystem.ts#L16-L25](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/scripts/FileSystem.ts#L16-L25) [src/TaskEither.ts#L1482-L1491](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/TaskEither.ts#L1482-L1491) [scripts/run.ts#L4-L20](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/scripts/run.ts#L4-L20)

## Behavior traces

Eight source walks describe consumer and maintainer behavior without executing it. The primary consumer paths cover optional-value extraction, JSON decoding, asynchronous failures, concurrent and sequential traversal, cleanup, and mutable references. The package path follows compilation through generated artifact assembly. Each trace identifies execution order and the branch that changes subsequent work.
- Getting-started flow: inverse(2) constructs Some(0.5), pipe invokes Option.map to construct Some(50), then getOrElse extracts 50; inverse(0) produces None, skips map's callback, and evaluates the fallback. — [docs/guides/getting-started.md#L43-L59](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/docs/guides/getting-started.md#L43-L59) [src/Option.ts#L336-L337](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/Option.ts#L336-L337) [src/Option.ts#L871-L874](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/Option.ts#L871-L874) [src/function.ts#L665-L668](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/function.ts#L665-L668)
- JSON flow: Json.parse → Either.tryCatch → JSON.parse → right on success or left(identity(error)) on throw; a subsequent Either.map runs only for Right. — [src/Json.ts#L37-L37](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/Json.ts#L37-L37) [src/Either.ts#L1393-L1399](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/Either.ts#L1393-L1399) [src/Either.ts#L470-L471](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/Either.ts#L470-L471) [test/Json.ts#L7-L13](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/test/Json.ts#L7-L13)
- Promise flow: tryCatchK captures arguments and constructs tryCatch; invoking the returned TaskEither calls f, awaits its Promise, and converts rejection or synchronous throw to Left; flatMap then preserves Left or invokes the Right continuation. — [src/TaskEither.ts#L249-L271](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/TaskEither.ts#L249-L271) [src/TaskEither.ts#L535-L538](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/TaskEither.ts#L535-L538) [src/EitherT.ts#L336-L339](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/EitherT.ts#L336-L339) [test/TaskEither.ts#L551-L568](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/test/TaskEither.ts#L551-L568)
- Parallel traversal: TaskEither.traverseReadonlyArrayWithIndex chooses ApT for empty input; otherwise Task traversal starts every indexed thunk through Promise.all, then Either traversal collects Rights or selects the first Left in input order. — [src/TaskEither.ts#L1600-L1616](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/TaskEither.ts#L1600-L1616) [src/Task.ts#L526-L530](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/Task.ts#L526-L530) [src/Either.ts#L1581-L1597](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/Either.ts#L1581-L1597) [test/TaskEither.ts#L758-L774](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/test/TaskEither.ts#L758-L774)
- Sequential traversal: the Seq helper invokes f(0,head) first, chains each remaining element through a Promise reduction, appends successful values, and skips later f invocations once the accumulated result is Left. — [src/TaskEither.ts#L1624-L1655](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/TaskEither.ts#L1624-L1655) [test/TaskEither.ts#L776-L792](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/test/TaskEither.ts#L776-L792)
- Resource flow: bracket delegates to bracketW; failed acquisition skips use/release, successful acquisition executes use, then release receives its resolved Either; release Left overrides the use result, while successful release restores that result. — [src/TaskEither.ts#L1501-L1519](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/TaskEither.ts#L1501-L1519) [src/EitherT.ts#L336-L339](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/EitherT.ts#L336-L339) [test/TaskEither.ts#L356-L402](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/test/TaskEither.ts#L356-L402)
- Reference flow: newIORef(1) returns an allocation thunk; IO.flatMap invokes it, ref.write(2) returns a mutation thunk, the next IO.flatMap executes that write, and ref.read observes the updated private value. — [src/IORef.ts#L18-L51](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/IORef.ts#L18-L51) [src/IO.ts#L78-L86](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/IO.ts#L78-L86) [test/IORef.ts#L12-L20](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/test/IORef.ts#L12-L20)
- Build flow: npm's prebuild cleans dist, two tsc configurations emit JavaScript/declarations, then main runs copyPackageJson → copyFiles → makeModules → fixHKT('es6') → fixHKT('lib'); run invokes the assembled effect and sets the process exit code. — [package.json#L15-L18](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/package.json#L15-L18) [scripts/build.ts#L79-L111](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/scripts/build.ts#L79-L111) [scripts/run.ts#L4-L20](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/scripts/run.ts#L4-L20) [tsconfig.build-es6.json#L1-L7](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/tsconfig.build-es6.json#L1-L7)

## Testing signals

Tests and CI were inspected, not executed; no passing result, coverage percentage, or benchmark result is established by this investigation. Runtime examples use Vitest globals and Node assertions, while dtslint separately checks inferred public types. The inspected cases exercise conversion boundaries, cleanup branches, traversal execution, references, serialization, and barrel exports. Coverage remains bounded, and several source-level limitations require distinguishing test intent from actual assertions.
- Vitest discovers test files under test/, excludes util.ts as a test entry, enables globals, and uses Istanbul for coverage; test/util.ts wraps Node assert.deepStrictEqual and assert.strictEqual. — [vite.config.ts#L4-L12](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/vite.config.ts#L4-L12) [test/util.ts#L1-L14](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/test/util.ts#L1-L14)
- Inspected CI runs npm install → npm run build --if-present → npm test on Node 20.12.2; npm test includes lint, formatting, dtslint, runtime tests, and docs, but the shown workflow does not invoke the separate coverage script. — [.github/workflows/main.yml#L16-L28](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/.github/workflows/main.yml#L16-L28) [package.json#L14-L27](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/package.json#L14-L27)
- dtslint/TaskEither.ts uses $ExpectType assertions for fallback unions and error transformations; dtslint has its own config extending the root config and disabling noUnusedLocals. — [dtslint/TaskEither.ts#L9-L56](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/dtslint/TaskEither.ts#L9-L56) [dtslint/tsconfig.json#L1-L9](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/dtslint/tsconfig.json#L1-L9) [package.json#L21-L21](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/package.json#L21-L21)
- TaskEither tests cover taskify's null/undefined error callbacks, callback errors, and repeated invocation; tryCatchK tests separately cover resolved Promises, rejected Promises, and synchronous throws. — [test/TaskEither.ts#L331-L354](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/test/TaskEither.ts#L331-L354) [test/TaskEither.ts#L551-L568](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/test/TaskEither.ts#L551-L568)
- bracket tests enumerate acquisition, use, and release Left branches and release precedence; the case named 'body throws' actually supplies useFailure returning Left, so it does not demonstrate cleanup after a rejected Promise. — [test/TaskEither.ts#L356-L402](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/test/TaskEither.ts#L356-L402) [src/TaskEither.ts#L1493-L1519](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/TaskEither.ts#L1493-L1519)
- TaskEither traversal tests assert that parallel execution still runs a later Right after an earlier Left, while sequential execution skips it; shared timing helpers also assert ApplicativePar versus ApplicativeSeq ordering. — [test/TaskEither.ts#L758-L792](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/test/TaskEither.ts#L758-L792) [test/TaskEither.ts#L319-L325](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/test/TaskEither.ts#L319-L325) [test/util.ts#L43-L56](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/test/util.ts#L43-L56)
- IORef tests cover read/write/modify and bound-method piping; Json tests cover valid/invalid parsing, circular serialization, and undefined; the index test checks that source modules other than internal/index appear in the barrel. — [test/IORef.ts#L7-L49](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/test/IORef.ts#L7-L49) [test/Json.ts#L7-L35](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/test/Json.ts#L7-L35) [test/index.ts#L23-L40](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/test/index.ts#L23-L40)
- Array and ReadonlyArray include fast-check chunksOf properties, but their generated predicates discard isDeepStrictEqual's result; the examined performance file constructs a Benchmark.Suite, and its historical comments were not treated as verified measurements. — [test/Array.ts#L977-L992](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/test/Array.ts#L977-L992) [test/ReadonlyArray.ts#L1044-L1059](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/test/ReadonlyArray.ts#L1044-L1059) [perf/TaskEither/traverseReadonlyArrayWithIndexSeq.ts#L6-L37](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/perf/TaskEither/traverseReadonlyArrayWithIndexSeq.ts#L6-L37)

## Risk map

These are source observations and explicitly labeled hypotheses, not confirmed vulnerabilities or reproduced failures. Sensitive boundaries in the inspected files include foreign callbacks, Promise rejection, filesystem operations, and npm publication. Searches across the examined public source and tooling were bounded; they do not establish whole-repository absence of authentication, secrets handling, networking, or other security behavior. Compatibility and test reliability deserve attention alongside runtime failure handling.
- bracket's cleanup guarantee explicitly concerns Left results; bracketW uses Promise sequencing without finally/catch around use, so an arbitrary rejected use Promise does not follow the release continuation shown here. — [src/TaskEither.ts#L1493-L1519](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/TaskEither.ts#L1493-L1519) [src/Task.ts#L128-L138](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/Task.ts#L128-L138) [test/TaskEither.ts#L395-L397](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/test/TaskEither.ts#L395-L397)
- taskify resolves callback errors to Left but calls the foreign function inside a Promise executor without a catch-to-Left adapter; it also applies the function with a null receiver, making thrown errors and receiver-dependent APIs distinct integration cases. — [src/TaskEither.ts#L1482-L1491](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/TaskEither.ts#L1482-L1491) [test/TaskEither.ts#L331-L354](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/test/TaskEither.ts#L331-L354)
- Default TaskEither traversal launches all input effects through Promise.all before examining Either outcomes; returning Left therefore does not cancel or prevent other effects, as the side-effect log test demonstrates. — [src/TaskEither.ts#L1600-L1603](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/TaskEither.ts#L1600-L1603) [src/Task.ts#L526-L530](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/Task.ts#L526-L530) [test/TaskEither.ts#L758-L774](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/test/TaskEither.ts#L758-L774)
- The build FileSystem adapter accepts arbitrary path strings and delegates directly to Node fs operations without root validation; inspected build call sites use package-relative inputs and dist outputs, so containment depends on their path construction and working directory. — [scripts/FileSystem.ts#L7-L32](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/scripts/FileSystem.ts#L7-L32) [scripts/build.ts#L13-L37](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/scripts/build.ts#L13-L37) [scripts/build.ts#L54-L60](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/scripts/build.ts#L54-L60)
- npm run release has a prerelease build hook and ultimately invokes child_process.exec('npm publish',{cwd:'dist'}); root prepublishOnly rejects publication, but the release path deliberately bypasses that root location. — [package.json#L19-L24](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/package.json#L19-L24) [scripts/release.ts#L9-L26](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/scripts/release.ts#L9-L26) [scripts/pre-publish.ts#L4-L6](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/scripts/pre-publish.ts#L4-L6)
- Both examined chunksOf property predicates compute isDeepStrictEqual(as,bs) without returning or asserting it; their explicit example assertion remains, but generated unequal results are not surfaced by that comparison statement. — [test/Array.ts#L977-L992](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/test/Array.ts#L977-L992) [test/ReadonlyArray.ts#L1044-L1059](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/test/ReadonlyArray.ts#L1044-L1059)
- Packaging/compatibility hypothesis: HKT.js and HKT.d.ts are moved during build, with both output formats targeting one shared declaration; changes here could disrupt URI module augmentation, and README warns that multiple installed fp-ts versions can cause compilation hangs. (inferred) — [scripts/build.ts#L63-L97](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/scripts/build.ts#L63-L97) [src/HKT.ts#L49-L70](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/HKT.ts#L49-L70) [README.md#L72-L76](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/README.md#L72-L76)
- Version-sensitive observations: package.json reports 2.16.11 while the lockfile root reports 2.16.7, and Json.parse's invalid-input test compares against a specific SyntaxError message; neither mismatch was executed or shown to fail. — [package.json#L2-L3](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/package.json#L2-L3) [package-lock.json#L2-L9](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/package-lock.json#L2-L9) [test/Json.ts#L7-L12](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/test/Json.ts#L7-L12)

## Extension points

Extension primarily happens through TypeScript interfaces and explicit instance arguments. New data types register with HKT dictionaries, then provide operations satisfying the relevant type classes. Existing factories accept caller-defined equality, ordering, error combination, and output accumulation policies. Maintainer tooling also exposes an injectable filesystem boundary and automatically derives packaged module entries from compiler output.
- A new data type can add a URI key through URItoKind module augmentation and supply Functor1-style instances; the HKT guide demonstrates this with Identity and explains the lookup mechanism. — [src/HKT.ts#L49-L70](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/HKT.ts#L49-L70) [docs/guides/HKT.md#L24-L42](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/docs/guides/HKT.md#L24-L42) [docs/guides/HKT.md#L58-L79](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/docs/guides/HKT.md#L58-L79)
- Type classes support multiple constructor arities and constrained variants; Functor2 keeps E generic, whereas Functor2C fixes E and includes an _E witness. — [src/Functor.ts#L25-L55](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/Functor.ts#L25-L55) [docs/guides/code-conventions.md#L52-L66](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/docs/guides/code-conventions.md#L52-L66)
- getApplicativeTaskValidation accepts a Task Apply instance and Semigroup<E>, allowing callers to choose execution policy and error concatenation instead of default first-error application. — [src/TaskEither.ts#L696-L705](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/TaskEither.ts#L696-L705) [src/TaskEither.ts#L667-L686](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/TaskEither.ts#L667-L686)
- Eq.fromEquals, Eq.struct, Eq.tuple, and Ord.fromCompare let consumers define domain comparison policies; ReadonlyMap.upsertAt then uses supplied key equality to preserve an existing equivalent key. — [src/Eq.ts#L38-L77](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/Eq.ts#L38-L77) [src/Ord.ts#L52-L55](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/Ord.ts#L52-L55) [src/ReadonlyMap.ts#L201-L218](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/ReadonlyMap.ts#L201-L218)
- ReadonlyArray.traverseWithIndex accepts an Applicative and combines results through of/map/ap; sequenceT and sequenceS similarly receive Apply instances, so their execution semantics come from the supplied dictionary. — [src/ReadonlyArray.ts#L1789-L1797](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/ReadonlyArray.ts#L1789-L1797) [src/Apply.ts#L588-L598](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/Apply.ts#L588-L598) [src/Apply.ts#L702-L713](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/Apply.ts#L702-L713)
- FromEither interfaces expose a lifting operation across HKT arities; chainOptionK combines that capability with Chain and an onNone callback to derive effect-specific Option sequencing. — [src/FromEither.ts#L33-L64](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/FromEither.ts#L33-L64) [src/FromEither.ts#L243-L250](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/FromEither.ts#L243-L250)
- Writer.getMonad receives a Monoid<W> and assembles Applicative/Chain behavior; getChain combines output from both stages using the caller's Semigroup.concat. — [src/Writer.ts#L160-L189](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/Writer.ts#L160-L189)
- Build computations receive a FileSystem environment that can be replaced structurally; module packaging derives names from dist/lib/*.js, excludes index, and writes per-module main/module/typings manifests. — [scripts/FileSystem.ts#L7-L14](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/scripts/FileSystem.ts#L7-L14) [scripts/build.ts#L11-L16](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/scripts/build.ts#L11-L16) [scripts/build.ts#L40-L76](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/scripts/build.ts#L40-L76)

## Contributor handoff

Begin with the affected public module, its shared helpers, runtime tests, and type assertions. Preserve inferred types, laziness, branch behavior, and compatibility aliases when making small changes. Tests and CI were inspected, not executed; any later validation must report actual commands and outcomes separately. This inventory is bounded and should guide targeted investigation rather than substitute for complete coverage.
- Read package.json, tsconfig.json, and vite.config.ts first: they distinguish source compilation, global test typing, runtime discovery, and the multi-stage npm test command. — [package.json#L9-L27](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/package.json#L9-L27) [tsconfig.json#L2-L28](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/tsconfig.json#L2-L28) [vite.config.ts#L4-L12](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/vite.config.ts#L4-L12)
- Consumer code is expected to enable strict TypeScript and import individual fp-ts/<module> paths; the README also requires a single installed fp-ts version. — [README.md#L72-L76](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/README.md#L72-L76) [docs/guides/getting-started.md#L26-L35](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/docs/guides/getting-started.md#L26-L35) [docs/guides/code-conventions.md#L24-L38](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/docs/guides/code-conventions.md#L24-L38)
- Follow established syntax and checks: no semicolons, single quotes, width 120, no trailing commas; ESLint requires sorted imports, rejects import cycles, and forbids spread arguments to Array.push. — [.prettierrc#L1-L6](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/.prettierrc#L1-L6) [.eslintrc.json#L25-L37](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/.eslintrc.json#L25-L37)
- For combinator edits, distinguish data-last public functions from instance adapters and dual overloads; preserve W widening, K lifting, E effectful matching, and constrained C instance conventions. — [src/function.ts#L773-L790](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/function.ts#L773-L790) [src/TaskEither.ts#L535-L538](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/TaskEither.ts#L535-L538) [docs/guides/code-conventions.md#L108-L110](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/docs/guides/code-conventions.md#L108-L110) [docs/guides/code-conventions.md#L198-L206](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/docs/guides/code-conventions.md#L198-L206)
- A new public source module needs barrel exposure: test/index.ts derives expected export names from source files, and scripts/build.ts derives module manifests from emitted JavaScript, with HKT handled specially. — [test/index.ts#L7-L27](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/test/index.ts#L7-L27) [test/index.ts#L30-L40](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/test/index.ts#L30-L40) [scripts/build.ts#L40-L76](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/scripts/build.ts#L40-L76)
- Keep @since/@category documentation and compatibility exports deliberate: TaskEither's deprecated taskEither/taskEitherSeq dictionaries remain exported, with guidance to prefer smaller instances; docs-ts excludes internal.ts. — [src/TaskEither.ts#L1778-L1817](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/TaskEither.ts#L1778-L1817) [src/Option.ts#L137-L151](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/src/Option.ts#L137-L151) [docs-ts.json#L1-L3](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/docs-ts.json#L1-L3)
- Tests and CI were inspected, not executed. For later authorized validation, the existing Vitest script can target the affected test file, dtslint checks signature inference, and npm test runs the full configured chain; coverage is a separate command. — [package.json#L14-L27](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/package.json#L14-L27) [vite.config.ts#L6-L10](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/vite.config.ts#L6-L10) [dtslint/TaskEither.ts#L13-L36](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/dtslint/TaskEither.ts#L13-L36) [.github/workflows/main.yml#L26-L28](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/.github/workflows/main.yml#L26-L28)
- Execution traps include prebuild deleting dist, postbuild rewriting generated declarations, npm test generating docs, and release publishing to npm; read-only onboarding must inspect these definitions without invoking them. — [package.json#L14-L24](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/package.json#L14-L24) [scripts/build.ts#L79-L97](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/scripts/build.ts#L79-L97) [scripts/release.ts#L22-L26](https://github.com/gcanti/fp-ts/blob/c0a6472121c67a2b083e62fcff13e7d022e39d8f/scripts/release.ts#L22-L26)

Source repository: https://github.com/gcanti/fp-ts
Full evidence corpus: https://github.com/Codevetter/codevetter/tree/main/benchmarks/repo-unpacks/fp-ts.json

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
