{"id":50558835,"url":"https://github.com/dominicegginton/functional-reader","last_synced_at":"2026-06-04T10:01:35.814Z","repository":{"id":358137544,"uuid":"1240145202","full_name":"dominicegginton/functional-reader","owner":"dominicegginton","description":"A purely functional, dependency-free dependency injection library for TypeScript based on the Reader Monad.","archived":false,"fork":false,"pushed_at":"2026-05-15T21:51:22.000Z","size":64,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-16T00:10:54.480Z","etag":null,"topics":["dependency-injection","functional-programming","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dominicegginton.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":["dominicegginton"]}},"created_at":"2026-05-15T20:17:38.000Z","updated_at":"2026-05-15T21:51:26.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/dominicegginton/functional-reader","commit_stats":null,"previous_names":["dominicegginton/functional-reader"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/dominicegginton/functional-reader","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dominicegginton%2Ffunctional-reader","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dominicegginton%2Ffunctional-reader/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dominicegginton%2Ffunctional-reader/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dominicegginton%2Ffunctional-reader/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dominicegginton","download_url":"https://codeload.github.com/dominicegginton/functional-reader/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dominicegginton%2Ffunctional-reader/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33899697,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-04T02:00:06.755Z","response_time":64,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dependency-injection","functional-programming","typescript"],"created_at":"2026-06-04T10:01:34.930Z","updated_at":"2026-06-04T10:01:35.802Z","avatar_url":"https://github.com/dominicegginton.png","language":"TypeScript","funding_links":["https://github.com/sponsors/dominicegginton"],"categories":[],"sub_categories":[],"readme":"# functional-reader\n\nA purely functional, dependency-free dependency injection library for TypeScript based on the Reader Monad.\n\n## Features\n\n- **Purely Functional**: Built on the Reader Monad pattern.\n- **Type-Safe**: Full TypeScript support with excellent type inference.\n- **Zero Dependencies**: Lightweight and fast.\n- **Composable**: Utilities for mapping, chaining, and adapting environments.\n- **Curried**: All functions are fully curried for maximum flexibility.\n\n## Comparison with Other Libraries\n\nWhile many libraries offer functional programming and dependency management in TypeScript, **functional-reader** focuses on being a lightweight, specialized tool.\n\n| Feature / Goal                                 | functional-reader        | fp-ts (Reader)           | lodash/fp                      |\n|------------------------------------------------|-------------------------|--------------------------|---------------------------------|\n| Reader Monad / Dependency Injection            | Core feature            | Included module          | Not available                  |\n| Zero runtime dependencies                      | Yes                    | No (requires fp-ts)      | No (lodash dependency)          |\n| TypeScript support \u0026 inference                 | Excellent               | Excellent                | Partial (not Reader-aware)      |\n| Lightweight / Minimal bundle                   | Yes                    | No (fp-ts is large)      | No (lodash is large)            |\n| API Simplicity                                | Minimal, approachable   | Broader/complex          | Simple, but not monadic         |\n| Curried / Point-Free APIs                     | Yes                     | Yes                      | Partial                         |\n| Explicit error handling (neverthrow compatible)| Yes                     | Yes (with effort)        | No                              |\n| Do-notation \u0026 record chaining helpers          | Included                | Included                 | No                              |\n| Pure FP without typeclass bloat                | Yes                     | No (full typeclass)      | Yes (pure, but not Reader)      |\n\n### Why functional-reader?\n- **Focused**: A small, dependency-free implementation of the Reader monad.\n- **TypeScript-native**: Designed for first-class type inference and autocompletion.\n- **Lightweight**: Zero dependencies and minimal bundle size overhead.\n- **Approachable**: A readable API that is easy to learn and integrate.\n- **Interoperable**: Designed to play well with other modern libraries like `neverthrow`.\n\n## Compatibility \u0026 Interoperability\n\n**functional-reader** is unopinionated, making it easy to integrate into existing TypeScript projects:\n\n| Interop Scenario                            | Support Description                                                           |\n|---------------------------------------------|------------------------------------------------------------------------------|\n| **neverthrow**                              | Returns or operates on `Result\u003cT, E\u003e` out-of-the-box.                         |\n| **fp-ts**                                   | Compatible API surface; easily migrated or combined.                          |\n| **RxJS / Promises**                         | Readers can be evaluated inside observables or async flows.                   |\n| **Legacy Code**                             | Since a Reader is just `(env) =\u003e value`, it plugs in directly everywhere.     |\n| **Standard Utilities**                      | Works seamlessly with standard JS utilities (lodash, ramda, etc.).            |\n\n## Install\n\n\u003e **Note**: functional-reader is distributed directly via this repository to emphasize transparency, autonomy, and source engagement over reliance on third-party registries. This approach allows users to review, audit, and tailor the library to their needs, while avoiding potential risks or restrictions imposed by centralized package platforms.\n\n```bash\n# Install the latest version from GitHub\nnpm install github:dominicegginton/functional-reader\n\n# Or install a specific version/tag\nnpm install github:dominicegginton/functional-reader#v1.0.0\n```\n\n## Documentation\n\n### Core Types\n\n- `Reader\u003cEnv, Result\u003e`: A computation that requires an environment `Env` to produce a result `Result`.\n\n### Construction\n\n- `of\u003cEnv, A\u003e(a: A)`: Creates a Reader that always returns `a`.\n- `defer\u003cEnv, A\u003e(f: () =\u003e Reader\u003cEnv, A\u003e)`: Creates a Reader that is lazily initialized when it is called.\n- `ask\u003cEnv\u003e()`: Creates a Reader that returns the entire environment.\n- `asks\u003cEnv, A\u003e(selector: (env: Env) =\u003e A)`: Creates a Reader that selects a part of the environment.\n- `asksReader\u003cEnv, A\u003e(f: (env: Env) =\u003e Reader\u003cEnv, A\u003e)`: Creates a Reader that selects a part of the environment and returns a new Reader.\n- `prop\u003cEnv, K extends keyof Env\u003e(key: K)`: Creates a Reader that extracts a specific property from the environment.\n- `pick\u003cEnv, K extends keyof Env\u003e(keys: readonly K[])`: Creates a Reader that selects multiple properties from the environment.\n\n### Transformation \u0026 Composition\n\n- `map\u003cA, B\u003e(f: (a: A) =\u003e B)`: Transforms the result of a Reader.\n- `mapTo\u003cB\u003e(value: B)`: Maps the result of a Reader to a constant value.\n- `chain\u003cA, Env, B\u003e(f: (a: A) =\u003e Reader\u003cEnv, B\u003e)`: Sequences two Readers where the second depends on the first.\n- `chainFirst\u003cA, Env, B\u003e(f: (a: A) =\u003e Reader\u003cEnv, B\u003e)`: Sequences two Readers where the second depends on the first, but returns the result of the first.\n- `flatten\u003cEnv, A\u003e(mma: Reader\u003cEnv, Reader\u003cEnv, A\u003e\u003e)`: Collapses a nested Reader into a single Reader.\n- `local\u003cEnvOuter, EnvInner\u003e(f: (outer: EnvOuter) =\u003e EnvInner)`: Adapts a Reader to a different environment type.\n- `provide\u003cEnv\u003e(env: Env)`: Provides an environment to a Reader, resulting in a Reader that requires no environment.\n- `ap\u003cEnv, A\u003e(fa: Reader\u003cEnv, A\u003e)`: Applies a function contained within a Reader to a value in another Reader.\n\n### Sequencing \u0026 Side Effects\n\n- `chainRight\u003cEnv, B\u003e(rb: Reader\u003cEnv, B\u003e)`: Sequences two Readers and returns the result of the second.\n- `chainLeft\u003cEnv, B\u003e(rb: Reader\u003cEnv, B\u003e)`: Sequences two Readers and returns the result of the first.\n- `tap\u003cEnv, A\u003e(sideEffect: (a: A, env: Env) =\u003e void)`: Performs a side effect without changing the Reader's result.\n\n### Combinators\n\n- `sequence\u003cEnv, A\u003e(readers: Array\u003cReader\u003cEnv, A\u003e\u003e)`: Combines an array of Readers into one that returns an array of results.\n- `traverse\u003cA, Env, B\u003e(f: (a: A) =\u003e Reader\u003cEnv, B\u003e)`: Maps over an array of values using a function that returns a Reader.\n- `struct\u003cEnv, S\u003e(readers: S)`: Combines an object of Readers into one that returns an object of results.\n- `zip\u003cEnv, A, B\u003e(rb: Reader\u003cEnv, B\u003e)`: Combines two Readers into a single Reader that returns a tuple of their results.\n- `iif\u003cEnv, A\u003e(predicate: (env: Env) =\u003e boolean, onTrue: Reader\u003cEnv, A\u003e, onFalse: Reader\u003cEnv, A\u003e)`: Conditionally chooses between two Readers based on the environment.\n- `when\u003cEnv, A\u003e(predicate: (env: Env) =\u003e boolean, reader: Reader\u003cEnv, A\u003e)`: Conditionally executes a Reader if the predicate is true.\n- `alt\u003cEnv, A, B\u003e(secondary: Reader\u003cEnv, B\u003e)`: Returns the result of the first Reader if it is not null or undefined, otherwise returns the result of the second Reader.\n\n### Do-Notation\n\n- `Do\u003cEnv\u003e()`: Initializes a \"Do\" block for chainable record compositions.\n- `bindTo\u003cK extends string\u003e(key: K)`: Wraps a Reader's result into a record with a specified key.\n- `bind\u003cK extends string, A, EnvB, B\u003e(key: K, f: (a: A) =\u003e Reader\u003cEnvB, B\u003e)`: Binds the result of a Reader to a key in a \"Do\" block.\n\n### Functional Utilities\n\n- `pipe(a, ...fns)`: Pipes a value through a series of functions.\n- `flow(...fns)`: Composes multiple functions into a single function.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdominicegginton%2Ffunctional-reader","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdominicegginton%2Ffunctional-reader","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdominicegginton%2Ffunctional-reader/lists"}