mrkeyoor.com_
Sat 08 Aug 21:57 UTC
npmUtilsupdated 08 Aug 2026

mathjs

mathjs is a broad mathematics toolkit for JavaScript and Node.js. It combines familiar numeric functions with arbitrary-precision decimals, fractions, complex numbers, physical units, dense and sparse matrices, symbolic derivatives, and a parser for calculator-style expressions. It can solve the awkward mixed-type jobs that built-in `Math` cannot, but its full feature set and expression runtime are much larger than a focused arithmetic package.

Verdict

mathjs earns its weight when a product genuinely needs several of its numeric types, units, matrices, and expression tools together. For one focused task, install the focused package; for untrusted expressions, current patching and process isolation are requirements, not optional hardening.

API stability3/5Core functions and data types are mature, and the library ships ESM, CommonJS, and TypeScript declarations from one documented surface. Major versions still carry observable semantic changes: version 15 changed percentage precedence, numeric literal parsing, matrix subset behavior, and the return type of `size`, while version 14 changed fractions to use bigint and adjusted matrix typings. Pin and test expressions when crossing majors.
Docs5/5The official site has separate guides for every data type, expression syntax and scope, security, configuration, extension, custom bundling, and hundreds of functions. Examples state output values and explain type propagation. The security page is notably candid about code-execution unknowns and resource exhaustion. The size and breadth can make discovery slower, but the material answers production questions rather than stopping at calculator demos.
Maintenance5/5Version 15.2.0 was published in April 2026, the repository was pushed in August 2026, and the history shows frequent feature, type, performance, documentation, and security fixes throughout 2025 and 2026. There are 139 open issues when pull requests are excluded, which is substantial, but active changes and explicit security fixes demonstrate ongoing ownership rather than backlog-only activity.
Ecosystem5/5mathjs recorded 3,396,403 downloads in the measured week and its repository has 15,066 stars. It integrates established packages for decimal, complex, and fraction arithmetic, works in Node and browsers, exports both module systems, includes TypeScript declarations, and supports custom types and injected functions. Few JavaScript libraries cover the same combination of expression parsing, units, matrices, and symbolic work.

Use it if

  • You need one API that can calculate with numbers, BigNumbers, fractions, complex values, units, arrays, and matrices
  • Your product needs a calculator expression language with variables, compiled expressions, or persistent parser scope
  • You need symbolic derivatives or expression-tree output alongside numeric evaluation
  • You are prepared to build a custom or number-only bundle when browser payload matters
Skip it if

Setup reality

`npm install mathjs` has no peer dependencies or native compilation, and the package exposes both ESM imports and a CommonJS `require` entry. Node 18 or newer is required. The easy full import hides the main production cost: the measured browser bundle is 192.1 KB gzipped and pulls nine runtime dependencies. Import named functions so a modern bundler can tree-shake, use `mathjs/number` when JavaScript numbers are enough, or create a custom instance from dependency collections such as `addDependencies`. Configuration belongs on an instance created with `create`; this also prevents one feature's precision or matrix choice from surprising unrelated code. BigNumber calculations are slower, are not supported by every function, and should begin from decimal strings when the source value must not first pass through binary floating point. If you use `evaluate`, remember that assignments mutate the supplied scope. Prefer a `Map`, compile repeated expressions once, and clear or discard parser instances between users because a parser retains variables and functions. Treat user formulas as hostile work: the official security page recommends disabling dangerous parser-visible functions and running evaluation in a worker or child process that can be terminated for time or memory abuse. Version 15.2.0 fixed two expression-parser vulnerabilities that allowed arbitrary JavaScript execution, so pinning an older major is not a harmless compatibility choice. Browser users should also avoid the complete prebuilt global bundle unless the payload is acceptable. There are no credentials or config files, but numeric type, precision, tolerances, matrix output, import policy, execution isolation, and bundle composition are application decisions you must make before shipping.

Patterns

Import only the functions you callcalculate-basic-values

import { round, sqrt, log } from 'mathjs';

round(Math.E, 3);       // 2.718
log(10000, 10);         // 4
sqrt(-4).toString();    // '2i'

Named imports give bundlers a chance to remove unused code. `sqrt(-4)` returns a Complex object, not a number.

Evaluate a formula against a scopeevaluate-with-scope

import { evaluate } from 'mathjs';

const scope = new Map([['price', 12.5], ['quantity', 4]]);
const total = evaluate('price * quantity', scope); // 50
evaluate('tax = total * 0.2', new Map([...scope, ['total', total]]));

A `Map` is the documented safer scope shape. Assignments write into the supplied scope, so do not reuse one across tenants or requests.

Compile once and evaluate many timescompile-repeated-expression

import { compile } from 'mathjs';

const formula = compile('a * x^2 + b');
for (const x of [1, 2, 3]) {
  console.log(formula.evaluate({ a: 2, b: 1, x }));
}

Compilation avoids reparsing the same expression. It does not make hostile formulas safe from expensive computation.

Use a parser with isolated statekeep-parser-state

import { parser } from 'mathjs';

const session = parser();
session.evaluate('rate = 1.08');
session.evaluate('price = 25');
session.evaluate('price * rate'); // 27
session.remove('price');
session.clear();

A parser retains assignments and function definitions. Create one per trusted session and clear or discard it when that session ends.

Create an isolated BigNumber instanceconfigure-big-numbers

import { all, create } from 'mathjs';

const math = create(all, {
  number: 'BigNumber',
  precision: 64,
  relTol: 1e-60,
  absTol: 1e-63,
});

math.evaluate('0.1 + 0.2').toString(); // '0.3'

Tune relative and absolute tolerances with precision. The docs warn that leaving number-oriented defaults can make high-precision comparisons misleading.

Keep rational arithmetic exactcalculate-fractions

import { add, divide, format, fraction } from 'mathjs';

const a = fraction(1, 3);
const b = fraction(3, 7);
format(add(a, b));       // '16/21'
format(divide(a, b));    // '7/9'

Version 14 moved Fraction internals to bigint. Convert to a JavaScript number only when losing exactness is acceptable.

Parse and convert physical unitsconvert-physical-units

import { unit } from 'mathjs';

const distance = unit('12.7 cm');
distance.to('inch').toString(); // '5 inch'
unit(20, 'degC').to('degF').toString(); // '68 degF'

Units carry dimensions and conversion rules. Keep them as Unit values until the boundary instead of stripping values early.

Multiply matrices and inspect the resultwork-with-matrices

import { det, matrix, multiply, size } from 'mathjs';

const a = matrix([[2, 0], [-1, 3]]);
const b = [[7, 1], [-2, 3]];
const product = multiply(a, b);
product.toArray(); // [[14, 2], [-13, 8]]
size(product);     // [2, 2]
det(b);            // 23

Mixed Array and Matrix input returns a Matrix. In version 15, `size` always returns a plain array.

Differentiate and simplify symbolicallydifferentiate-expression

import { derivative, simplify } from 'mathjs';

const d = derivative('x^3 + 2*x', 'x');
d.toString(); // '3 * x ^ 2 + 2'
simplify('(x + x) * 2').toString(); // '4 * x'

These functions produce expression nodes. Exact formatting can change across versions, so test mathematical meaning instead of snapshotting whitespace.

Parse an expression tree and emit LaTeXrender-expression-latex

import { parse } from 'mathjs';

const node = parse('sqrt(x / x + 1)');
console.log(node.toString());
console.log(node.toTex());

`toTex()` returns a string for a renderer such as MathJax. It does not render or sanitize HTML for you.

Remove risky functions from user expressionslimit-expression-api

import { all, create } from 'mathjs';

const math = create(all);
const limitedEvaluate = math.evaluate;
const blocked = () => { throw new Error('disabled in formulas'); };

math.import({
  import: blocked,
  createUnit: blocked,
  reviver: blocked,
  evaluate: blocked,
  parse: blocked,
  simplify: blocked,
  derivative: blocked,
  resolve: blocked,
}, { override: true });

limitedEvaluate('sqrt(16)'); // 4

This follows the official hardening pattern but is not a complete sandbox. Run untrusted work in a killable worker or child process with resource limits.

Create a tree-shakeable custom buildbuild-small-instance

import {
  create,
  addDependencies,
  divideDependencies,
  formatDependencies,
  fractionDependencies,
} from 'mathjs';

const math = create({
  addDependencies,
  divideDependencies,
  formatDependencies,
  fractionDependencies,
});

math.format(math.add(math.fraction(1, 3), math.fraction(1, 6))); // '1/2'

A function's dependency collection can still pull several data types. Use imports from `mathjs/number` when number-only behavior is enough.

Alternatives

PackageRegistryPick it when
decimal.jsnpmYou need dependable arbitrary-precision decimal arithmetic without a general math environment
ml-matrixnpmLinear algebra is the main job and you do not need units, symbolic expressions, or a calculator parser
expr-evalnpmYou need a smaller expression evaluator with a narrower feature surface
nerdamernpmSymbolic algebra, equations, and manipulation matter more than mixed numeric data types