tinyfunk
The tiniest of functional libraries.
Documentation
Motivation
Most popular functional libraries, like Ramda, are quite large. To use them in a frontend project, it's common to import only the bits you need (to keep the bundle size down) like this:
const assoc = const map = const merge = // etc.
But multiple require
statements take up extra space, since many js
code compression tools (including uglifyjs
) don't mangle strings. The AST overhead required to bundle the various modules adds an additional size penalty, not to mention the extra compute time to parse the twisted flow of the AST, which adds to a longer perceived load time.
tinyfunk
takes a different approach. It exports a single module to minimize AST overhead and obviate the repeated require statements. You just destructure the functions you need in one go:
const assoc map merge =
Where possible, it also composes more complex functions by reusing basic ones. A good example is compose
, implemented as so:
const compose =
With uglifyes
, this mangles down to the following. I doubt you'll find a smaller implementation.
const I=
Caveat emptor
In an effort to keep tinyfunk
lean and mean  and most of all, tiny  I've taken a few shortcuts.

None of the exported functions perform typechecking of arguments.
If typechecking is a runtime debug tool you tend to lean on, then you'll need to look elsewhere. 
Many of the function combinators only support unary functions.
This includescompose
,converge
,juxt
,pipe
,thrush
, etc. Unary functions are easily composable, readily portable, and so much simpler (ie: tinier) to support. 
Unlike other popular FP libraries, each exported function only has a single job.
For example, Ramda'smap
supports "mapping" over functors, objects, and even functions. Intinyfunk
, those various jobs are supported instead bymap
,mapObj
, andcompose
respectfully. So be sure to use the right tool for the job at hand.
API
If you've lived with FP long enough, you are likely familiar with most of the functions listed below. So I've opted to leave out the lengthy descriptions and include only the signatures. I'll be adding more functions as I need them, but if you see any of your favorites missing, just post an issue and I'll be sure to consider it.
Function  Signature 

add 
Number > Number > Number 
append 
a > [a] > [a] 
apply 
(a... > b) > [a] > b 
assoc 
k > v > { k: v } > { k: v } 
assocPath 
[k] > v > { k: v } > { k: v } 
call 
(a... > b) > a... > b 
compose 
((y > z), ..., (a > b)) > a > z 
composeP 
((y > Promise z), ..., (a > Promise b)) > a > Promise z 
concat 
Semigroup a => a > a > a 
cond 
[[(a > Boolean), (a > b)]] > a > b 
constant 
a > () > a 
converge 
(b... > c) > [(a > b)] > a > c 
curry 
((a, b, ...) > z) > a > b > ... > z 
curryN 
Number > ((a, b, ...) > z) > a > b > ... > z 
defaultTo 
a > a > a 
dissoc 
k > { k: v } > { k: v } 
dissocPath 
[k] > { k: v } > { k: v } 
either 
(a > Boolean) > (a > Boolean) > (a > Boolean) 
evolve 
{ k: (v > v) } > { k: v } > { k: v } 
filter 
(a > Boolean) > [a] > [a] 
find 
(a > Boolean) > [a] > a 
flatten 
[a] > [b] 
flip 
(a > b > c) > (b > a > c) 
head 
[a] > a 
identity 
a > a 
ifElse 
(a > Boolean) > (a > b) > (a > b) > (a > b) 
indexBy 
(v > k) > [v] > { k: v } 
init 
[a] > [a] 
is 
Constructor > a > Boolean 
join 
String > [a] > String 
juxt 
[(a > b)] > a > [b] 
keys 
{ k: v } > [k] 
last 
[a] > a 
length 
[a] > Number 
map 
Functor f => (a > b) > f a > f b 
mapObj 
(v > k > v) > { k: v } > { k: v } 
match 
RegExp > String > [String] 
merge 
{ k: v } > { k: v } > { k: v } 
multiply 
Number > Number > Number 
nAry 
Number > (a... > b) > (a... > b) 
not 
a > a 
objOf 
k > v > { k: v } 
omit 
[k] > { k: v } > { k: v } 
partial 
(a... > b) > [a] > a... > b 
partialRight 
(a... > b) > [a] > a... > b 
path 
[k] > { k: v } > v 
pathEq 
[k] > v > { k: v } > Boolean 
pick 
[k] > { k: v } > { k: v } 
pipe 
((a > b), ..., (y > z)) > a > z 
pipeP 
((a > Promise b), ..., (y > Promise z)) > a > Promise z 
pluck 
k > [{ k: v }] > [v] 
prepend 
a > [a] > [a] 
prop 
k > { k: v } > v 
propEq 
k > v > { k: v } > Boolean 
props 
[k] > { k: v } > [v] 
reduce 
Foldable f => (b > a > b) > b > f a > b 
reduceObj 
(a > v > k > a) > a > { k: v } > a 
reduceP 
(b > a > Promise b) > b > [a] > Promise b 
reduceRight 
Foldable f => (b > a > b) > b > f a > b 
reduceRightP 
(b > a > Promise b) > b > [a] > Promise b 
replace 
RegExp > String > String > String 
slice 
Number > Number > [a] > [a] 
sort 
((a, a) > Number) > [a] > [a] 
sortBy 
Ord b => (a > b) > [a] > [a] 
split 
RegExp > String > [String] 
tail 
[a] > [a] 
take 
Number > [a] > [a] 
tap 
(a > b) > a > a 
test 
RegExp > String > Boolean 
then 
(a > Promise b) > a > Promise b 
thrush 
a > (a > b) > b 
unapply 
([a] > b) > a... > b 
unary 
(a... > b) > (a > b) 
uniqBy 
(a > String) > [a] > [a] 
unit 
a > () 
unless 
(a > Boolean) > (a > a) > a > a 
useWith 
(b... > c) > [(a > b)] > a... > c 
values 
{ k: v } > [v] 
when 
(a > Boolean) > (a > a) > a > a 
zipObj 
[k] > [v] > { k: v } 
Dependents
I use tinyfunk
everyday to make cool things. Maybe you do, too. If so, let me know with a PR, and we can add your cool things to this list.
puddles
 Tiny vdom app framework. Pure Redux. No boilerplate.  Built with ❤️ ontinyfunk
.