Skip to content

OOFP — Functional Programming for TypeScript

Type-safe algebraic data types, dependency injection, and composition utilities for building real-world TypeScript applications.

Type-safe by default

Every function, every monad, every composition is fully typed. TypeScript inference works end-to-end with no casts needed.

Real-world patterns

Built for production applications. ReaderTaskEither provides dependency injection, async operations, and error handling in a single type.

Zero dependencies

No runtime dependencies. Tree-shakeable modular imports keep your bundle small.

Composable

Everything composes with pipe and flow. Build complex workflows from simple, reusable functions.

import * as RTE from "@oofp/core/reader-task-either";
import * as E from "@oofp/core/either";
import { pipe } from "@oofp/core/pipe";
interface AppContext {
db: Database;
logger: Logger;
}
const findUser = (id: string) =>
pipe(
RTE.ask<AppContext>(),
RTE.chaint((ctx) => ctx.db.findUser(id)),
RTE.tapRTE((user) => logAccess(user)),
);
// Execute at the boundary
const result = await RTE.run(appContext)(findUser("123"))();
pipe(
result,
E.fold(
(error) => console.error(error),
(user) => console.log(user),
),
);