A lightweight, TypeScript-first functional programming library
- TypeScript-first with excellent type inference
- Lightweight (~3KB gzipped) with strong tree-shaking
- Auto-curried functions for point-free programming
- Zero dependencies
- Modern ESM + CJS dual package
- Full test coverage (100%)
npm install functional.js # or
pnpm add functional.js # or
yarn add functional.jsimport { pipe, map, filter, reduce } from "functional.js";
const data = [1, 2, 3, 4, 5, 6];
const result = pipe(
data,
filter((x) => x % 2 === 0),
map((x) => x * 2),
reduce((acc, x) => acc + x)
);
console.log(result); import { curry } from "functional.js";
const add = curry((a: number, b: number) => a + b);
add(1, 2);
add(1)(2);
const add5 = add(5);
add5(10);import { flow, map, filter, pluck } from "functional.js";
interface User {
name: string;
age: number;
active: boolean;
}
const getActiveUserNames = flow(
filter<User>((u) => u.active),
map((u) => u.name.toUpperCase())
);
const users: User[] = [
{ name: "Alice", age: 30, active: true },
{ name: "Bob", age: 25, active: false },
{ name: "Charlie", age: 35, active: true }
];
console.log(getActiveUserNames(users));curry(fn)— Auto-curry any functioncompose(...fns)— Right-to-left function compositionpipe(value, ...fns)— Left-to-right data pipelineflow(...fns)— Left-to-right function composition
map(fn, array)— Transform array elementsfilter(fn, array)— Filter array by predicatereduce(fn, array)— Reduce array (no initial value)fold(fn, initial, array)— Fold array with initial valueflatMap(fn, array)— Map and flatteneach(fn, array)— Iterate over arraypartition(fn, array)— Split array by predicategroup(fn, array)— Group array by key functionzip(arr1, arr2)— Zip two arrays togetherzipWith(fn, arr1, arr2)— Zip with a combining functionuniq(array)— Remove duplicatesuniqBy(fn, array)— Remove duplicates by key function
first(fn, array)— Find first matching elementlast(fn, array)— Find last matching elementevery(fn, array)— Check if all elements matchany(fn, array)— Check if any element matchesbest(comparator, array)— Find best element by comparator
prop(key)— Create property accessorpluck(key, array)— Extract property from array of objectspick(keys, obj)— Select properties from objectomit(keys, obj)— Remove properties from objectpath(pathArray, obj)— Get nested property valueassoc(key, value, obj)— Set property immutablydissoc(key, obj)— Remove property immutablyassign(obj1, obj2)— Merge objects
identity(x)— Return input unchangedconstant(x)— Create constant functiontap(fn)— Execute side effect and return input
isFunction,isObject,isArrayisString,isNumber,isDate,isRegExpexists,truthy,falsy
All functions have full TypeScript support with proper type inference:
import { pipe, map, filter } from "functional.js";
const numbers = [1, 2, 3, 4, 5];
const result = pipe(
numbers,
filter((x) => x > 2),
map((x) => x.toString())
);| Library | Bundle Size | TypeScript | Auto-Curry | Notes |
|---|---|---|---|---|
| functional.js | ~3KB | Strong | Yes | Data-last, zero dependencies |
| Ramda | ~50KB | Limited | Yes | Data-last, large API |
| lodash/fp | ~24KB | Good | Yes | Data-last wrappers over lodash |
| underscore | ~17KB | Limited | No | Data-first utilities |
| fp-ts | ~15KB | Strong | No | Types-first, higher learning curve |
Benchmarks run on Node.js 24.13.0 (macOS), using small/medium/large scenarios with isolated processes, warmups, and median results.
Highlights from the latest run:
- functional.js wins 31 of 45 ops/sec metrics
- functional.js is fastest cold start at 0.81 ms
- functional.js leads 4 of 9 memory benchmarks (lowest heap delta)
- functional.js is up to 3.86x faster than the runner-up when it leads (1.57x average)
Use these prompts with AI assistants (ChatGPT, Claude, Cursor, etc.) to get accurate functional.js help:
- "Show me how to use pipe in functional.js with TypeScript"
- "Compare functional.js pipe with Ramda pipe"
- "Explain when to use flow versus compose in functional.js"
- "Give me a functional.js example for transforming an array of users"
- "Convert this Ramda code to functional.js: [paste code]"
- "Migrate lodash/fp chain to functional.js pipe: [paste code]"
- "Replace compose with flow using functional.js: [paste code]"
- "How do I transform an array of users with functional.js"
- "Show me point-free style with functional.js"
- "Build a reusable pipeline with flow and use it on data"
- "Why does reduce throw on this input in functional.js: [paste code]"
- "My curried function returns another function, what did I do wrong in functional.js: [paste code]"
MIT License © Lee Crossley
Inspired by Ramda, lodash/fp, and fp-ts. Built for modern TypeScript development.




