reduce-css-calc
reduce-css-calc is a small build-time function that accepts a CSS value string and simplifies every calc() expression it can understand. It evaluates plain arithmetic, combines compatible units, converts absolute lengths, angles, times, frequencies, and resolutions when needed, and leaves expressions containing incompatible units in a shorter calc() form. It is the low-level calculation engine historically used by tools such as postcss-calc, not a PostCSS plugin, stylesheet parser, runtime React helper, or browser polyfill.
Keep it when compatibility with an existing 2.x build chain matters. For new work, postcss-calc or @csstools/css-calc has a healthier maintenance story and understands a broader CSS toolchain.
Use it if
- You are maintaining a build tool that already calls this exact function and need behavior compatible with the 2.x parser
- You need to reduce calc() inside isolated CSS value strings without constructing a PostCSS pipeline
- You want same-unit arithmetic and supported absolute-unit conversion while preserving expressions that still need browser layout information
- You need a CommonJS package with no peer dependencies and can accept an old, narrow API
- You are starting a modern PostCSS pipeline: this package only transforms a value string, while postcss-calc is the maintained plugin that walks declarations and exposes plugin options
- You need current CSS math beyond calc(): the source matcher only recognizes calc and vendor-prefixed calc, so min(), max(), clamp(), and newer typed arithmetic are outside its parser
- Your generated CSS can contain uppercase units such as PX: issue 75 and its unmerged pull request have documented that parse error since November 2021
- You need first-party TypeScript declarations or an ESM export map: version 2.1.8 publishes neither types nor an exports field and points main at a transpiled CommonJS file
- You want active parser maintenance: the last functional release was 2.1.8 in January 2021, while the two 2024 commits only raised the development Node version and added a security policy
Setup reality
Installation is only npm install reduce-css-calc, with no peer dependency, native compilation, credentials, or config file. The published entry point is transpiled CommonJS, so require('reduce-css-calc') returns the function directly; a default import usually works through Node or bundler CommonJS interop, but there is no exports map or first-party declaration file to make TypeScript and mixed-module projects explicit. The function accepts a CSS value string and an optional numeric precision as its second positional argument. It is not a PostCSS plugin and does not parse a stylesheet, so calling it on an entire CSS file is the wrong integration. Apply it to declaration values yourself or choose postcss-calc. Unsupported work is not handled uniformly: incompatible units remain as calc(), expressions involving var() may be partly simplified around the variable, and any calc containing env() or constant() is skipped. Invalid math can throw synchronously, including division by zero and division by a unit-bearing value, so build tools processing third-party CSS should catch errors and report the source declaration. The default precision is five decimal places. The parser also carries old grammar edges, including the open uppercase PX failure, so test the exact CSS emitted by upstream tools before putting it into a production minification path.
Patterns
Evaluate a unitless calc expressionreduce-basic-arithmetic
const reduceCSSCalc = require('reduce-css-calc');
const output = reduceCSSCalc('calc((6 / 2) - (4 * 2) + 1)');
console.log(output); // -4The return value is always a string, even when the expression reduces to a plain number.
Combine values with the same unitcombine-same-units
const reduceCSSCalc = require('reduce-css-calc');
console.log(reduceCSSCalc('calc(3rem * 2 - 1rem)'));
// 5remA unit can be multiplied or divided only by a unitless number; dividing 2rem by 1rem throws.
Control decimal precisionset-decimal-precision
const reduceCSSCalc = require('reduce-css-calc');
console.log(reduceCSSCalc('calc(1 / 3)')); // 0.33333
console.log(reduceCSSCalc('calc(1 / 3)', 10)); // 0.3333333333Precision is the second positional argument and defaults to five decimal places.
Flatten nested calc expressionssimplify-nested-calc
const reduceCSSCalc = require('reduce-css-calc');
const value = 'calc(100% - calc(50% + 25px))';
console.log(reduceCSSCalc(value));
// calc(50% - 25px)The percentage and length cannot be resolved together at build time, so the remaining mixed-unit expression stays in calc().
Reduce every calc in one value stringreduce-multiple-functions
const reduceCSSCalc = require('reduce-css-calc');
const value = 'translate(calc(10px + 5px), calc(2em * 3))';
console.log(reduceCSSCalc(value));
// translate(15px, 6em)The value parser walks every recognized calc() function while preserving surrounding CSS tokens.
Combine compatible time unitsconvert-compatible-time-units
const reduceCSSCalc = require('reduce-css-calc');
console.log(reduceCSSCalc('calc(1s - 50ms)'));
// 0.95sAbsolute lengths, angles, times, frequencies, and resolutions can be converted; relative lengths such as rem and px are not interchangeable.
Leave layout-dependent math for the browserpreserve-incompatible-units
const reduceCSSCalc = require('reduce-css-calc');
console.log(reduceCSSCalc('calc(100% + 1px)'));
// calc(100% + 1px)Percentage plus length depends on layout, so unchanged calc() output is the correct result rather than a failed reduction.
Preserve a custom property while folding constantssimplify-around-css-variable
const reduceCSSCalc = require('reduce-css-calc');
const value = 'calc(10px - (100px + var(--offset)))';
console.log(reduceCSSCalc(value));
// calc(-90px - var(--offset))The variable itself is never resolved, but constant terms around it may still move or combine. Test generated output if exact formatting matters.
Pass env expressions through unchangedpreserve-safe-area-expression
const reduceCSSCalc = require('reduce-css-calc');
const value = 'calc(env(safe-area-inset-left) + 12px)';
console.log(reduceCSSCalc(value));
// calc(env(safe-area-inset-left) + 12px)The source skips the entire calc() when its contents include env() or the older constant() spelling.
Catch invalid CSS math in a build stephandle-invalid-math
const reduceCSSCalc = require('reduce-css-calc');
try {
reduceCSSCalc('calc(500px / 0)');
} catch (error) {
console.error('Invalid declaration:', error.message);
}Division by zero throws synchronously instead of returning the original expression.
Handle a vendor-prefixed calc functionreduce-prefixed-calc
const reduceCSSCalc = require('reduce-css-calc');
console.log(reduceCSSCalc('-webkit-calc(1px + 1px)'));
// 2pxThe matcher accepts vendor-prefixed calc names. If mixed units remain, the prefix is retained on the surviving expression.
Apply the reducer to declaration valuestransform-declaration-values
const reduceCSSCalc = require('reduce-css-calc');
const declarations = {
width: 'calc(100% - 10px - 20px)',
margin: 'calc(4px * 2)',
};
for (const property of Object.keys(declarations)) {
declarations[property] = reduceCSSCalc(declarations[property]);
}
console.log(declarations);
// { width: 'calc(100% - 30px)', margin: '8px' }Pass individual declaration values, not a complete stylesheet. Use postcss-calc when you need parsing, source locations, and stylesheet traversal.
Alternatives
| Package | Registry | Pick it when |
|---|---|---|
| postcss-calc | npm | Choose it when you already use PostCSS and want calc reduction across declarations with current plugin maintenance. |
| @csstools/css-calc | npm | Choose it when you need a current CSS math solver with broader syntax and typed calculation support. |
| lightningcss | npm | Choose it when calculation folding should be part of a fast parser, transformer, minifier, and browser-targeting pipeline. |