A practical functional library for JavaScript programmers.
npx @tessl/cli install tessl/npm-ramda@0.31.0Ramda 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.
Package: ramda
NPM: npm install ramda
CDN: https://cdn.jsdelivr.net/npm/ramda@0.31.3/dist/ramda.min.js
GitHub: ramda/ramda
// Full library import
import * as R from 'ramda';
// Named imports for specific functions
import { map, filter, compose, pipe } from 'ramda';
// Individual function imports (tree-shaking friendly)
import map from 'ramda/es/map.js';
import filter from 'ramda/es/filter.js';// Full library import
const R = require('ramda');
// Destructured imports
const { map, filter, compose, pipe } = require('ramda');
// Individual function imports
const map = require('ramda/src/map');
const filter = require('ramda/src/filter');All multi-argument Ramda functions are automatically curried, enabling powerful partial application:
// Basic usage
const add = R.add(2);
add(3); // => 5
// With placeholder for flexible partial application
const subtract = R.subtract(R.__, 2);
subtract(10); // => 8 (10 - 2)// Left-to-right composition with pipe
const processData = R.pipe(
R.map(R.multiply(2)),
R.filter(R.gt(R.__, 10)),
R.reduce(R.add, 0)
);
// Right-to-left composition with compose
const transform = R.compose(
R.join(' '),
R.map(R.toUpper),
R.split('')
);// Working with arrays
const numbers = [1, 2, 3, 4, 5];
const doubled = R.map(R.multiply(2), numbers); // => [2, 4, 6, 8, 10]
// Working with objects
const person = { name: 'John', age: 30 };
const older = R.assoc('age', 31, person); // => { name: 'John', age: 31 }Ramda follows three core principles that distinguish it from other JavaScript libraries:
All Ramda functions treat their inputs as immutable, never modifying the original data:
const original = [1, 2, 3];
const modified = R.append(4, original);
// original: [1, 2, 3] (unchanged)
// modified: [1, 2, 3, 4] (new array)Functions take operations first, data last, making them ideal for composition and partial application:
// Ramda style (function-first, data-last)
const isEven = R.modulo(R.__, 2);
const evenNumbers = R.filter(isEven, [1, 2, 3, 4, 5]);
// vs. Array methods (data-first)
// [1, 2, 3, 4, 5].filter(x => x % 2 === 0)All multi-parameter functions are curried by default:
// These are all equivalent
R.add(1, 2); // => 3
R.add(1)(2); // => 3
const add1 = R.add(1);
add1(2); // => 3R.__)The placeholder allows flexible partial application:
const divide = R.divide(R.__, 2); // Divide by 2
divide(10); // => 5
const subtractFrom10 = R.subtract(10, R.__);
subtractFrom10(3); // => 7Ramda provides comprehensive functionality across multiple domains:
94 functions for array manipulation, transformation, and analysis
// Core list operations
R.map(fn, list) // Transform each element
R.filter(predicate, list) // Select matching elements
R.reduce(reducer, init, list) // Fold/accumulate values
R.find(predicate, list) // Find first match
R.groupBy(keyFn, list) // Group by computed key
// Examples
const users = [
{ name: 'Alice', age: 25, active: true },
{ name: 'Bob', age: 30, active: false },
{ name: 'Carol', age: 35, active: true }
];
const activeUsers = R.filter(R.prop('active'), users);
const usersByAge = R.groupBy(R.prop('age'), users);
const names = R.map(R.prop('name'), users);57 functions for object manipulation, property access, and transformation
// Core object operations
R.prop('key', obj) // Get property value
R.assoc('key', val, obj) // Set property (immutable)
R.dissoc('key', obj) // Remove property (immutable)
R.merge(obj1, obj2) // Shallow merge objects
R.path(['a', 'b'], obj) // Get nested property
// Examples
const user = { name: 'John', address: { city: 'NYC', zip: '10001' } };
const name = R.prop('name', user); // => 'John'
const city = R.path(['address', 'city'], user); // => 'NYC'
const updated = R.assoc('age', 30, user); // Add age property
const withoutAddress = R.dissoc('address', user); // Remove address55 functions for function composition, currying, and higher-order operations
// Function composition and transformation
R.compose(...fns) // Right-to-left composition
R.pipe(...fns) // Left-to-right composition
R.curry(fn) // Curry a function manually
R.partial(fn, args) // Partial application
R.flip(fn) // Reverse first two arguments
// Examples
const processText = R.pipe(
R.trim, // Remove whitespace
R.toLower, // Convert to lowercase
R.split(' '), // Split into words
R.filter(R.complement(R.isEmpty)), // Remove empty strings
R.map(R.take(3)) // Take first 3 chars of each word
);
processText(' Hello World '); // => ['hel', 'wor']58 functions for mathematical operations, comparisons, and logical operations
// Math operations (13 functions)
R.add(a, b) // Addition
R.multiply(a, b) // Multiplication
R.divide(a, b) // Division
R.subtract(a, b) // Subtraction
R.mean(numbers) // Average
R.sum(numbers) // Sum array
// Logic & Relation operations (45 functions)
R.and(a, b) // Logical AND
R.or(a, b) // Logical OR
R.not(val) // Logical NOT
R.allPass(predicates) // All predicates true
R.anyPass(predicates) // Any predicate true
R.cond(pairs) // Conditional logic
// Examples
const isPositiveEven = R.allPass([
R.gt(R.__, 0), // Greater than 0
x => R.modulo(x, 2) === 0 // Even number
]);
const mathOps = R.pipe(
R.multiply(2), // Double the value
R.add(10), // Add 10
R.divide(R.__, 4) // Divide by 4
);13 functions for string manipulation and type checking
// String operations (8 functions)
R.toUpper(str) // Convert to uppercase
R.toLower(str) // Convert to lowercase
R.trim(str) // Remove whitespace
R.split(separator, str) // Split string
R.replace(pattern, replacement, str) // Replace text
R.match(regex, str) // Match pattern
R.test(regex, str) // Test pattern
// Type checking (5 functions)
R.type(val) // Get type name
R.is(Type, val) // Check if instance of type
R.isNil(val) // Check if null/undefined
R.propIs(Type, prop, obj) // Check property type
// Examples
const validateEmail = R.pipe(
R.trim, // Remove whitespace
R.toLower, // Normalize case
R.test(/^[\w\.-]+@[\w\.-]+\.\w+$/), // Validate format
);
const processNames = R.map(R.pipe(
R.trim,
R.replace(/\s+/g, ' '), // Normalize whitespace
R.split(' '), // Split into parts
R.map(R.pipe(R.head, R.toUpper)) // Get initials
));const userLens = R.lensProp('user');
const nameLens = R.lensPath(['user', 'name']);
const state = { user: { name: 'John', age: 30 } };
const updated = R.set(nameLens, 'Jane', state);
// => { user: { name: 'Jane', age: 30 } }const xf = R.compose(
R.map(R.add(1)),
R.filter(R.gt(R.__, 5)),
R.take(3)
);
R.transduce(xf, R.flip(R.append), [], [1, 2, 3, 4, 5, 6, 7, 8, 9]);
// => [6, 7, 8]// Instead of: users.filter(user => user.active).map(user => user.name)
const getActiveUserNames = R.pipe(
R.filter(R.prop('active')),
R.map(R.prop('name'))
);This comprehensive functional programming approach makes Ramda ideal for building robust, maintainable applications with predictable data transformations and elegant function composition.