# @csstools/css-calc

> Solve CSS math expressions

Latest version **3.3.0** (published 2026-07-22) · MIT license · 0 weekly downloads

## Install

```sh
npm install @csstools/css-calc
pnpm add @csstools/css-calc
yarn add @csstools/css-calc
bun add @csstools/css-calc
```

## Health

**Score 60/100 (C)** — status: active.

Positive: esm support; no vulnerabilities; recently updated; high maintenance score.

Warnings: low downloads; no types.

## Facts

| | |
|---|---|
| Version | 3.3.0 |
| Published | 2026-07-22 |
| First published | 2023-02-21 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | none |
| Module format | ESM |
| Node | >=20.19.0 |
| Dependencies | 0 |
| Unpacked size | 43.2 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 1052 |
| Maintainers | jonathantneal, alaguna, romainmenke |
| Keywords | calc, css |

## Links

- npm: https://www.npmjs.com/package/@csstools/css-calc
- Repository: https://github.com/csstools/postcss-plugins
- Homepage: https://github.com/csstools/postcss-plugins/tree/main/packages/css-calc#readme
- Issues: https://github.com/csstools/postcss-plugins/issues
- Funding: https://github.com/sponsors/csstools
- npm.io page: https://npm.io/package/@csstools/css-calc

## Alternatives

- [style-dictionary](https://npm.io/package/style-dictionary.md) — 2.0M weekly downloads
- [postcss-merge-idents](https://npm.io/package/postcss-merge-idents.md) — 1.7M weekly downloads
- [@fontsource/noto-sans](https://npm.io/package/@fontsource/noto-sans.md) — 93.0K weekly downloads
- [uglifycss](https://npm.io/package/uglifycss.md) — 71.6K weekly downloads
- [mat4-interpolate](https://npm.io/package/mat4-interpolate.md) — 23.3K weekly downloads

## Recent versions

- 3.3.0 (latest) — 2026-07-22
- 3.2.1 — 2026-05-13
- 3.2.0 — 2026-04-12
- 3.1.1 — 2026-02-13
- 3.1.0 — 2026-02-12
- 3.0.1 — 2026-02-10
- 3.0.0 — 2026-01-14
- 2.1.4 — 2025-05-27
- 2.1.3 — 2025-04-19
- 2.1.2 — 2025-02-23
- 2.1.1 — 2024-12-27
- 2.1.0 — 2024-11-11
- 2.0.4 — 2024-11-01
- 2.0.3 — 2024-10-23
- 2.0.2 — 2024-10-10
- … 17 more at https://npm.io/package/@csstools/css-calc/versions

## README

# CSS Calc <img src="https://cssdb.org/images/css.svg" alt="for CSS" width="90" height="90" align="right">

[<img alt="npm version" src="https://img.shields.io/npm/v/@csstools/css-calc.svg" height="20">][npm-url]
[<img alt="Build Status" src="https://github.com/csstools/postcss-plugins/actions/workflows/test.yml/badge.svg?branch=main" height="20">][cli-url]
[<img alt="Discord" src="https://shields.io/badge/Discord-5865F2?logo=discord&logoColor=white">][discord]

Implemented from : https://drafts.csswg.org/css-values-4/ on 2023-02-17

## Usage

Add [CSS calc] to your project:

```bash
npm install @csstools/css-calc @csstools/css-parser-algorithms @csstools/css-tokenizer --save-dev
```

### With string values :

```mjs
import { calc } from '@csstools/css-calc';

// '20'
console.log(calc('calc(10 * 2)'));
```

### With component values :

```mjs
import { stringify, tokenizer } from '@csstools/css-tokenizer';
import { parseCommaSeparatedListOfComponentValues } from '@csstools/css-parser-algorithms';
import { calcFromComponentValues } from '@csstools/css-calc';

const t = tokenizer({
	css: 'calc(10 * 2)',
});

const tokens = [];

{
	while (!t.endOfFile()) {
		tokens.push(t.nextToken());
	}

	tokens.push(t.nextToken()); // EOF-token
}

const result = parseCommaSeparatedListOfComponentValues(tokens, {});

// filter or mutate the component values

const calcResult = calcFromComponentValues(result, { precision: 5, toCanonicalUnits: true });

// filter or mutate the component values even further

const calcResultStr = calcResult.map((componentValues) => {
	return componentValues.map((x) => stringify(...x.tokens())).join('');
}).join(',');

// '20'
console.log(calcResultStr);
```

### Options

#### `precision` :

The default precision is fairly high.
It aims to be high enough to make rounding unnoticeable in the browser.

You can set it to a lower number to suit your needs.

```mjs
import { calc } from '@csstools/css-calc';

// '0.3'
console.log(calc('calc(1 / 3)', { precision: 1 }));
// '0.33'
console.log(calc('calc(1 / 3)', { precision: 2 }));
```

#### `globals` :

Pass global values as a map of key value pairs.

> Example : Relative color syntax (`lch(from pink calc(l / 2) c h)`) exposes color channel information as ident tokens.
> By passing globals for `l`, `c` and `h` it is possible to solve nested `calc()`'s.

```mjs
import { calc } from '@csstools/css-calc';

const globals = new Map([
	['a', '10px'],
	['b', '2rem'],
]);

// '20px'
console.log(calc('calc(a * 2)', { globals: globals }));
// '6rem'
console.log(calc('calc(b * 3)', { globals: globals }));
```

#### `toCanonicalUnits` :

By default this package will try to preserve units.
The heuristic to do this is very simplistic.
We take the first unit we encounter and try to convert other dimensions to that unit.

This better matches what users expect from a CSS dev tool.

If you want to have outputs that are closes to CSS serialized values you can pass `toCanonicalUnits: true`.

```mjs
import { calc } from '@csstools/css-calc';

// '20hz'
console.log(calc('calc(0.01khz + 10hz)', { toCanonicalUnits: true }));

// '20hz'
console.log(calc('calc(10hz + 0.01khz)', { toCanonicalUnits: true }));

// '0.02khz' !!!
console.log(calc('calc(0.01khz + 10hz)', { toCanonicalUnits: false }));

// '20hz'
console.log(calc('calc(10hz + 0.01khz)', { toCanonicalUnits: false }));
```

[cli-url]: https://github.com/csstools/postcss-plugins/actions/workflows/test.yml?query=workflow/test
[discord]: https://discord.gg/bUadyRwkJS
[npm-url]: https://www.npmjs.com/package/@csstools/css-calc

[CSS calc]: https://github.com/csstools/postcss-plugins/tree/main/packages/css-calc

---
_Source: https://npm.io/package/@csstools/css-calc · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
