{"id":10916,"library":"fp-ts","title":"fp-ts: Functional Programming in TypeScript","description":"fp-ts is a TypeScript library providing tools for typed functional programming, including popular algebraic data types like `Option`, `Either`, `IO`, and `Task`, alongside type classes such as `Functor`, `Applicative`, and `Monad`. It uniquely implements Higher Kinded Types to enable robust functional patterns within TypeScript's type system. The current stable version is 2.16.11, last published approximately 8 months ago as of the current date. While actively maintained, recent announcements indicate that the `fp-ts` project is officially merging with the Effect-TS ecosystem, with Effect-TS being positioned as the successor, akin to `fp-ts v3`. This transition implies a future shift in development focus towards the Effect-TS project, offering enhanced capabilities and support for new users.","status":"maintenance","version":"2.16.11","language":"javascript","source_language":"en","source_url":"https://github.com/gcanti/fp-ts","tags":["javascript","typescript","algebraic-data-types","functional-programming"],"install":[{"cmd":"npm install fp-ts","lang":"bash","label":"npm"},{"cmd":"yarn add fp-ts","lang":"bash","label":"yarn"},{"cmd":"pnpm add fp-ts","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"The `pipe` function is fundamental for functional composition. While `require` works in CommonJS, ESM `import` is preferred for tree-shaking and modern module resolution.","wrong":"const { pipe } = require('fp-ts/function');","symbol":"pipe","correct":"import { pipe } from 'fp-ts/function';"},{"note":"fp-ts modules are typically imported as namespaces (e.g., `* as O`) for brevity and to avoid name collisions. Importing individual constructors like `Option` directly is less idiomatic for module-level exports.","wrong":"import { Option } from 'fp-ts/Option';","symbol":"O (Option namespace)","correct":"import * as O from 'fp-ts/Option';"},{"note":"Similar to `Option`, `Either` and other Algebraic Data Types (ADTs) are best imported as a namespace for convenient access to all module exports (constructors, combinators, etc.).","wrong":"import { Either } from 'fp-ts/Either';","symbol":"E (Either namespace)","correct":"import * as E from 'fp-ts/Either';"},{"note":"Task is a core asynchronous type. Consistent use of ESM `import * as T` is recommended for tree-shaking and modern module resolution.","wrong":"const T = require('fp-ts/Task');","symbol":"T (Task namespace)","correct":"import * as T from 'fp-ts/Task';"}],"quickstart":{"code":"import { pipe } from 'fp-ts/function';\nimport * as O from 'fp-ts/Option';\nimport * as E from 'fp-ts/Either';\nimport * as TE from 'fp-ts/TaskEither';\n\ninterface User {\n  id: number;\n  name: string;\n  email?: string;\n}\n\nconst fetchUser = (userId: number): TE.TaskEither<Error, string> =>\n  TE.tryCatch(\n    () =>\n      fetch(`https://jsonplaceholder.typicode.com/users/${userId}`).then(\n        (res) => {\n          if (!res.ok) {\n            throw new Error(`HTTP error! status: ${res.status}`);\n          }\n          return res.text();\n        },\n      ),\n    (reason) => new Error(String(reason)),\n  );\n\nconst parseJson = (s: string): E.Either<Error, User> =>\n  E.tryCatch(\n    () => JSON.parse(s) as User,\n    (reason) => new Error(`Failed to parse JSON: ${String(reason)}`),\n  );\n\nconst getUserEmail = (user: User): O.Option<string> =>\n  O.fromNullable(user.email);\n\n// Example usage:\nconst run = async () => {\n  console.log('Fetching user 1...');\n  const result = await pipe(\n    fetchUser(1), // Fetch user with ID 1\n    TE.flatMapEither(parseJson), // Parse the response as JSON, converting TaskEither<Error, string> to TaskEither<Error, User>\n    TE.map(getUserEmail), // Map the User to an Option<string> (email)\n    TE.match(\n      (error) => `Error fetching user 1: ${error.message}`,\n      (emailOption) =>\n        pipe(\n          emailOption,\n          O.match(\n            () => 'User 1 email not found.',\n            (email) => `User 1 email: ${email}`,\n          ),\n        ),\n    ),\n  )();\n  console.log(result);\n\n  console.log('\\nAttempting to fetch non-existent user 999...');\n  const invalidResult = await pipe(\n    fetchUser(999), // Fetch a non-existent user, likely resulting in an HTTP error\n    TE.flatMapEither(parseJson), // This step will likely be skipped or fail due to the upstream error\n    TE.map(getUserEmail),\n    TE.match(\n      (error) => `Error fetching user 999: ${error.message}`,\n      (emailOption) =>\n        pipe(\n          emailOption,\n          O.match(\n            () => 'User 999 email not found.',\n            (email) => `User 999 email: ${email}`,\n          ),\n        ),\n    ),\n  )();\n  console.log(invalidResult);\n};\n\nrun();","lang":"typescript","description":"This quickstart demonstrates fetching data, parsing JSON, and safely accessing optional properties using `TaskEither`, `Either`, `Option`, and the `pipe` function for functional composition and error handling. It shows how to chain operations that can fail (HTTP request, JSON parsing) and gracefully handle missing values."},"warnings":[{"fix":"For new projects or major architectural shifts, consider starting with Effect-TS. For existing `fp-ts v2` projects, continue with `fp-ts` for now, but be aware of the long-term migration path to Effect-TS. Review Effect-TS documentation for compatibility and migration guides.","message":"The `fp-ts` project is officially merging with the Effect-TS ecosystem. Effect-TS is positioned as the successor to `fp-ts v2` (effectively `fp-ts v3`), indicating a significant shift in the future roadmap and potentially requiring migration for new projects or major upgrades.","severity":"breaking","affected_versions":">=2.16.11"},{"fix":"Use `npm ls fp-ts` to check installed versions and ensure only one `fp-ts` version is present, or that others are `deduped`. Resolve conflicting dependencies by adjusting package versions or using `npm dedupe`.","message":"Installing multiple versions of `fp-ts` in a single project is known to cause `tsc` to hang during compilation. Ensure only a single version is installed.","severity":"gotcha","affected_versions":">=2.0.0"},{"fix":"Enable the `strict` flag in your `tsconfig.json` to ensure full type safety and compatibility with fp-ts's design principles.","message":"fp-ts is designed for use with TypeScript's `strict` flag turned on. Developing without strict mode may lead to unexpected type behaviors or errors.","severity":"gotcha","affected_versions":">=2.0.0"},{"fix":"Replace calls to `chain` or `chainW` with their `flatMap` equivalents. For example, `pipe(optionValue, O.chain(f))` becomes `pipe(optionValue, O.flatMap(f))`.","message":"The `chain` and `chainW` functions have been superseded by `flatMap` for most data types (e.g., `Option`, `Either`, `Task`, `Array`). While `chain` is still available, `flatMap` is the preferred and more idiomatic name.","severity":"deprecated","affected_versions":">=2.14.0"},{"fix":"Update usage from `mapLeft` to `mapError` and `bimap` to `mapBoth` where applicable to align with the latest API naming conventions.","message":"Functions like `mapLeft` (for `Either`, `These`, etc.) and `bimap` have been aliased or replaced by `mapError` and `mapBoth` respectively for consistency.","severity":"deprecated","affected_versions":">=2.16.0"},{"fix":"Avoid using `fp-ts@2.13.0`. Upgrade to `2.13.1` or newer immediately if you encounter module resolution issues related to this version.","message":"Version `2.13.0` was identified as a 'BROKEN RELEASE' due to issues with the `exports` field in `package.json`, which affected module resolution in `node12/nodenext` environments and could lead to import errors.","severity":"breaking","affected_versions":"2.13.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Run `npm ls fp-ts` to identify duplicate versions. Use `npm dedupe` or manually adjust your `package.json` dependencies to ensure only a single `fp-ts` version is installed and deduped.","cause":"Multiple versions of `fp-ts` are installed in your `node_modules` tree, confusing TypeScript's module resolution.","error":"tsc hangs during compilation"},{"fix":"Migrate your imports to ESM syntax: `import { pipe } from 'fp-ts/function';` instead of `const { pipe } = require('fp-ts/function');`.","cause":"Attempting to use CommonJS `require()` syntax for `fp-ts` modules in an ECMAScript Module (ESM) environment (e.g., Node.js with `\"type\": \"module\"` or certain bundler configurations).","error":"ReferenceError: require is not defined"},{"fix":"Ensure you are using the correct import path `import { pipe } from 'fp-ts/function';`. Verify your `tsconfig.json` `moduleResolution` and `module` settings are compatible with modern Node.js or your bundler (e.g., `\"moduleResolution\": \"bundler\"` or `\"node16\"`).","cause":"Incorrect import path for `pipe` or other utilities, or a TypeScript configuration that doesn't correctly resolve module exports, especially if migrating from older versions or different module systems.","error":"Property 'pipe' does not exist on type 'typeof import(\"/node_modules/fp-ts/lib/function\")'"},{"fix":"Enable `\"strict\": true` in your `tsconfig.json`. Ensure all possible cases of ADTs (e.g., `None`/`Some` for `Option`, `Left`/`Right` for `Either`) are handled using `match`, `fold`, or type guards.","cause":"Type errors commonly arise when TypeScript's `strict` mode is disabled, leading to `fp-ts` functions inferring looser types than expected, or when `fp-ts` ADTs are not handled exhaustively or correctly.","error":"Type 'Foo' is not assignable to type 'Bar'. Argument of type 'Foo' is not assignable to parameter of type 'Bar'."}],"ecosystem":"npm"}