TS Belt - fast, modern, and practical utility library for FP in TypeScript
Marcin Dziewulski
Posted on December 6, 2021
Repo: https://github.com/mobily/ts-belt
Documentation: https://mobily.github.io/ts-belt/
Introduction
After a few intensive months of after-hours work, I have finally published a new version of ts-belt
(v3). As stated in the post title, TS Belt is a fast, modern, and practical utility library for functional programming in TypeScript.
Technical Background
TS Belt has been built in ReScript (and its Belt stdlib). ReScript generates highly performant JavaScript code, as well as it automatically generates TypeScript types with genType. Moreover, I've added a few codemods to the building process to provide even more code optimizations and cleaner TypeScript signatures.
Usage
If you're into FP and use TypeScript on a daily basis work, I assume you know at least one of these:
- Ramda
- Rambda
- Remeda
- lodash/fp
All of them follow FP principles: pipe
operator, immutable data, no side-effects, etc. TS Belt does the same, however it provides the data-first
approach for a single function call, which feels more natural, makes your code more readable and it’s much more developer-friendly, and the data-last approach for usage within the pipeline. Take a look at the following examples to see the difference:
// ⬇️ ts-belt → single function call
A.map([1, 2, 3, 4], value => value * 3)
// ⬇️ ramda/rambda → single function call
map(value => value * 3, [1, 2, 3, 4])
// ⬇️ ts-belt → pipe
pipe(
[1, 2, 3, 4],
A.filter(value => value % 2 === 0),
A.map(value => value * 3),
)
// ⬇️ ramda/rambda → pipe
pipe(
filter(value => value % 2 === 0),
map(value => value * 3),
)([1, 2, 3, 4])
// ⬇️ lodash/fp → pipe
_.flow(
_.filter(value => value % 2 === 0),
_.map(value => value * 3),
)([1, 2, 3, 4])
Last but not least, TS Belt provides two interesting implementations of data types:
- Option - represents the existence and nonexistence of a value by wrapping it with the Option type
- Result - describes the result of a certain operation without relying on exceptions
Performance
TS Belt is super fast, and I really mean it, it's even faster than the fastest library so far, Rambda.
Sample results (tested on MacBook Pro, M1 Pro, 2021):
map (single function call)
✔ @mobily/ts-belt 82,703,682.92 ops/sec ±0.83% (96 runs) fastest
✔ remeda 2,966,512.35 ops/sec ±1.53% (92 runs) -96.41%
✔ ramda 19,918,582.19 ops/sec ±0.55% (97 runs) -75.92%
✔ rambda 81,584,073.11 ops/sec ±0.88% (87 runs) -1.35%
✔ lodash/fp 13,133,226.26 ops/sec ±0.59% (99 runs) -84.12%
filter (single function call)
✔ @mobily/ts-belt 48,676,101.83 ops/sec ±0.29% (100 runs) fastest
✔ remeda 2,588,688.05 ops/sec ±1.49% (98 runs) -94.68%
✔ ramda 16,662,990.83 ops/sec ±0.78% (97 runs) -65.77%
✔ rambda 46,443,339.53 ops/sec ±1.91% (99 runs) -4.59%
✔ lodash/fp 6,620,795.22 ops/sec ±0.79% (96 runs) -86.40%
reduce (single function call)
✔ @mobily/ts-belt 44,890,901.88 ops/sec ±0.17% (102 runs) fastest
✔ remeda 2,660,391.00 ops/sec ±0.82% (99 runs) -94.07%
✔ ramda 10,199,240.77 ops/sec ±0.65% (97 runs) -77.28%
✔ rambda 15,497,091.42 ops/sec ±1.86% (92 runs) -65.48%
✔ lodash/fp 9,658,372.21 ops/sec ±1.08% (100 runs) -78.48%
groupBy (single function call)
✔ @mobily/ts-belt 6,453,084.49 ops/sec ±0.14% (97 runs) fastest
✔ remeda 1,783,616.20 ops/sec ±1.05% (95 runs) -72.36%
✔ ramda 1,667,720.10 ops/sec ±1.30% (93 runs) -74.16%
✔ rambda 6,100,470.04 ops/sec ±1.29% (94 runs) -5.46%
✔ lodash/fp 3,123,622.49 ops/sec ±0.89% (97 runs) -51.59%
map → filter → reduce
✔ @mobily/ts-belt 254,251.22 ops/sec ±0.20% (99 runs) fastest
✔ remeda 25,231.20 ops/sec ±1.76% (92 runs) -90.08%
✔ ramda 131,950.08 ops/sec ±0.41% (98 runs) -48.10%
✔ rambda 250,385.53 ops/sec ±0.39% (102 runs) -1.52%
✔ lodash/fp 66,034.82 ops/sec ±0.71% (98 runs) -74.03%
deepFlat → uniq → groupBy
✔ @mobily/ts-belt 2,297,096.07 ops/sec ±0.20% (99 runs) fastest
✔ remeda 494,070.92 ops/sec ±2.33% (98 runs) -78.49%
✔ ramda 281,192.43 ops/sec ±0.97% (93 runs) -87.76%
✔ rambda 1,767,868.03 ops/sec ±1.10% (98 runs) -23.04%
✔ lodash/fp 528,949.75 ops/sec ±1.15% (98 runs) -76.97%
Full benchmark results can be found here: https://mobily.github.io/ts-belt/benchmarks/introduction
Installation
To install ts-belt
use either npm
or yarn
:
yarn add @mobily/ts-belt
npm install @mobily/ts-belt --save
Final Comments
TS Belt combines all of the good things you can find in other similar libraries: the developer-friendly data-first approach, good-looking and detailed documentation, great TypeScript support, and it's fast! 🚀
Let me know if you're willing to use ts-belt
in your project! Also, don't forget to give a star to ts-belt
on Github. Any feedback or suggestions are appreciated as well.
Happy coding! 😊
Posted on December 6, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
December 6, 2021