A practical functional library for JavaScript programmers.
npx @tessl/cli install tessl/npm-ramda@0.31.00
# Ramda - Functional Programming Library
1
2
Ramda is a practical functional programming library for JavaScript that emphasizes a purer functional style. It provides 272 functions designed to make your code more readable, maintainable, and powerful through immutability, function composition, and automatic currying.
3
4
## Package Information
5
6
**Package:** `ramda`
7
**NPM:** `npm install ramda`
8
**CDN:** `https://cdn.jsdelivr.net/npm/ramda@0.31.3/dist/ramda.min.js`
9
**GitHub:** [ramda/ramda](https://github.com/ramda/ramda)
10
11
## Core Imports
12
13
### ESM (ES6 Modules)
14
15
```javascript { .api }
16
// Full library import
17
import * as R from 'ramda';
18
19
// Named imports for specific functions
20
import { map, filter, compose, pipe } from 'ramda';
21
22
// Individual function imports (tree-shaking friendly)
23
import map from 'ramda/es/map.js';
24
import filter from 'ramda/es/filter.js';
25
```
26
27
### CommonJS
28
29
```javascript { .api }
30
// Full library import
31
const R = require('ramda');
32
33
// Destructured imports
34
const { map, filter, compose, pipe } = require('ramda');
35
36
// Individual function imports
37
const map = require('ramda/src/map');
38
const filter = require('ramda/src/filter');
39
```
40
41
## Basic Usage
42
43
### Automatic Currying
44
45
All multi-argument Ramda functions are automatically curried, enabling powerful partial application:
46
47
```javascript { .api }
48
// Basic usage
49
const add = R.add(2);
50
add(3); // => 5
51
52
// With placeholder for flexible partial application
53
const subtract = R.subtract(R.__, 2);
54
subtract(10); // => 8 (10 - 2)
55
```
56
57
### Function Composition
58
59
```javascript { .api }
60
// Left-to-right composition with pipe
61
const processData = R.pipe(
62
R.map(R.multiply(2)),
63
R.filter(R.gt(R.__, 10)),
64
R.reduce(R.add, 0)
65
);
66
67
// Right-to-left composition with compose
68
const transform = R.compose(
69
R.join(' '),
70
R.map(R.toUpper),
71
R.split('')
72
);
73
```
74
75
### Immutable Data Operations
76
77
```javascript { .api }
78
// Working with arrays
79
const numbers = [1, 2, 3, 4, 5];
80
const doubled = R.map(R.multiply(2), numbers); // => [2, 4, 6, 8, 10]
81
82
// Working with objects
83
const person = { name: 'John', age: 30 };
84
const older = R.assoc('age', 31, person); // => { name: 'John', age: 31 }
85
```
86
87
## Architecture
88
89
Ramda follows three core principles that distinguish it from other JavaScript libraries:
90
91
### 1. Immutability
92
All Ramda functions treat their inputs as immutable, never modifying the original data:
93
94
```javascript { .api }
95
const original = [1, 2, 3];
96
const modified = R.append(4, original);
97
// original: [1, 2, 3] (unchanged)
98
// modified: [1, 2, 3, 4] (new array)
99
```
100
101
### 2. Function-First, Data-Last
102
Functions take operations first, data last, making them ideal for composition and partial application:
103
104
```javascript { .api }
105
// Ramda style (function-first, data-last)
106
const isEven = R.modulo(R.__, 2);
107
const evenNumbers = R.filter(isEven, [1, 2, 3, 4, 5]);
108
109
// vs. Array methods (data-first)
110
// [1, 2, 3, 4, 5].filter(x => x % 2 === 0)
111
```
112
113
### 3. Automatic Currying
114
All multi-parameter functions are curried by default:
115
116
```javascript { .api }
117
// These are all equivalent
118
R.add(1, 2); // => 3
119
R.add(1)(2); // => 3
120
const add1 = R.add(1);
121
add1(2); // => 3
122
```
123
124
### The Placeholder (`R.__`)
125
126
The placeholder allows flexible partial application:
127
128
```javascript { .api }
129
const divide = R.divide(R.__, 2); // Divide by 2
130
divide(10); // => 5
131
132
const subtractFrom10 = R.subtract(10, R.__);
133
subtractFrom10(3); // => 7
134
```
135
136
## Capabilities
137
138
Ramda provides comprehensive functionality across multiple domains:
139
140
### [List/Array Functions →](list-functions.md)
141
**94 functions** for array manipulation, transformation, and analysis
142
143
```javascript { .api }
144
// Core list operations
145
R.map(fn, list) // Transform each element
146
R.filter(predicate, list) // Select matching elements
147
R.reduce(reducer, init, list) // Fold/accumulate values
148
R.find(predicate, list) // Find first match
149
R.groupBy(keyFn, list) // Group by computed key
150
151
// Examples
152
const users = [
153
{ name: 'Alice', age: 25, active: true },
154
{ name: 'Bob', age: 30, active: false },
155
{ name: 'Carol', age: 35, active: true }
156
];
157
158
const activeUsers = R.filter(R.prop('active'), users);
159
const usersByAge = R.groupBy(R.prop('age'), users);
160
const names = R.map(R.prop('name'), users);
161
```
162
163
### [Object Functions →](object-functions.md)
164
**57 functions** for object manipulation, property access, and transformation
165
166
```javascript { .api }
167
// Core object operations
168
R.prop('key', obj) // Get property value
169
R.assoc('key', val, obj) // Set property (immutable)
170
R.dissoc('key', obj) // Remove property (immutable)
171
R.merge(obj1, obj2) // Shallow merge objects
172
R.path(['a', 'b'], obj) // Get nested property
173
174
// Examples
175
const user = { name: 'John', address: { city: 'NYC', zip: '10001' } };
176
177
const name = R.prop('name', user); // => 'John'
178
const city = R.path(['address', 'city'], user); // => 'NYC'
179
const updated = R.assoc('age', 30, user); // Add age property
180
const withoutAddress = R.dissoc('address', user); // Remove address
181
```
182
183
### [Function Functions →](function-functions.md)
184
**55 functions** for function composition, currying, and higher-order operations
185
186
```javascript { .api }
187
// Function composition and transformation
188
R.compose(...fns) // Right-to-left composition
189
R.pipe(...fns) // Left-to-right composition
190
R.curry(fn) // Curry a function manually
191
R.partial(fn, args) // Partial application
192
R.flip(fn) // Reverse first two arguments
193
194
// Examples
195
const processText = R.pipe(
196
R.trim, // Remove whitespace
197
R.toLower, // Convert to lowercase
198
R.split(' '), // Split into words
199
R.filter(R.complement(R.isEmpty)), // Remove empty strings
200
R.map(R.take(3)) // Take first 3 chars of each word
201
);
202
203
processText(' Hello World '); // => ['hel', 'wor']
204
```
205
206
### [Math & Logic Functions →](math-logic.md)
207
**58 functions** for mathematical operations, comparisons, and logical operations
208
209
```javascript { .api }
210
// Math operations (13 functions)
211
R.add(a, b) // Addition
212
R.multiply(a, b) // Multiplication
213
R.divide(a, b) // Division
214
R.subtract(a, b) // Subtraction
215
R.mean(numbers) // Average
216
R.sum(numbers) // Sum array
217
218
// Logic & Relation operations (45 functions)
219
R.and(a, b) // Logical AND
220
R.or(a, b) // Logical OR
221
R.not(val) // Logical NOT
222
R.allPass(predicates) // All predicates true
223
R.anyPass(predicates) // Any predicate true
224
R.cond(pairs) // Conditional logic
225
226
// Examples
227
const isPositiveEven = R.allPass([
228
R.gt(R.__, 0), // Greater than 0
229
x => R.modulo(x, 2) === 0 // Even number
230
]);
231
232
const mathOps = R.pipe(
233
R.multiply(2), // Double the value
234
R.add(10), // Add 10
235
R.divide(R.__, 4) // Divide by 4
236
);
237
```
238
239
### [String & Type Functions →](string-type.md)
240
**13 functions** for string manipulation and type checking
241
242
```javascript { .api }
243
// String operations (8 functions)
244
R.toUpper(str) // Convert to uppercase
245
R.toLower(str) // Convert to lowercase
246
R.trim(str) // Remove whitespace
247
R.split(separator, str) // Split string
248
R.replace(pattern, replacement, str) // Replace text
249
R.match(regex, str) // Match pattern
250
R.test(regex, str) // Test pattern
251
252
// Type checking (5 functions)
253
R.type(val) // Get type name
254
R.is(Type, val) // Check if instance of type
255
R.isNil(val) // Check if null/undefined
256
R.propIs(Type, prop, obj) // Check property type
257
258
// Examples
259
const validateEmail = R.pipe(
260
R.trim, // Remove whitespace
261
R.toLower, // Normalize case
262
R.test(/^[\w\.-]+@[\w\.-]+\.\w+$/), // Validate format
263
);
264
265
const processNames = R.map(R.pipe(
266
R.trim,
267
R.replace(/\s+/g, ' '), // Normalize whitespace
268
R.split(' '), // Split into parts
269
R.map(R.pipe(R.head, R.toUpper)) // Get initials
270
));
271
```
272
273
## Advanced Patterns
274
275
### Lenses for Deep Updates
276
277
```javascript { .api }
278
const userLens = R.lensProp('user');
279
const nameLens = R.lensPath(['user', 'name']);
280
281
const state = { user: { name: 'John', age: 30 } };
282
const updated = R.set(nameLens, 'Jane', state);
283
// => { user: { name: 'Jane', age: 30 } }
284
```
285
286
### Transducers for Efficient Processing
287
288
```javascript { .api }
289
const xf = R.compose(
290
R.map(R.add(1)),
291
R.filter(R.gt(R.__, 5)),
292
R.take(3)
293
);
294
295
R.transduce(xf, R.flip(R.append), [], [1, 2, 3, 4, 5, 6, 7, 8, 9]);
296
// => [6, 7, 8]
297
```
298
299
### Point-Free Style Programming
300
301
```javascript { .api }
302
// Instead of: users.filter(user => user.active).map(user => user.name)
303
const getActiveUserNames = R.pipe(
304
R.filter(R.prop('active')),
305
R.map(R.prop('name'))
306
);
307
```
308
309
This comprehensive functional programming approach makes Ramda ideal for building robust, maintainable applications with predictable data transformations and elegant function composition.