mrkeyoor.com_
Sun 09 Aug 06:55 UTC
npmWeb Frontendupdated 09 Aug 2026

icss-replace-symbols

A tiny, single-purpose helper for the linking stage of Interoperable CSS. Give it a PostCSS syntax tree and a map of token names to replacement strings, and it rewrites matching tokens inside declaration values and media-query parameters. It deliberately does not touch selectors or property names. The package is mostly encountered as an old transitive dependency in CSS Modules toolchains; for new code, its maintained successor is the replaceSymbols export from icss-utils.

Verdict

Keep it when an old CSS Modules toolchain already depends on its exact behavior. Do not choose it for new work; icss-utils is the direct successor and avoids adopting a package last released in 2017.

API stability4/5The 1.1.0 surface is only a default replaceSymbols(root, translations) function plus a compiled named replaceAll helper, and the behavior has not changed since May 2017. The historical tests pin useful details such as leaving selectors and property names alone, treating dotted names as whole tokens, and not recursively replacing newly inserted text. That is stable by inactivity, though, not a promise backed by current releases or a stated compatibility policy.
Docs2/5The package README clearly states the two inputs and the two places it rewrites, with one import example and short declaration and media-query illustrations. It does not document the CommonJS .default requirement, in-place mutation, undefined return value, the exported replaceAll helper, supported PostCSS versions, TypeScript use, or the matching edge cases covered by the old test suite. The repository link now lands on icss-utils documentation rather than a maintained page for this package.
Maintenance1/5npm version 1.1.0 was published on May 21, 2017, and the original GitHub location redirects to css-modules/icss-utils. That destination's latest tagged release is 5.1.0 from November 2020, while its most recent push was a dependency-security commit in January 2023. The npm package is not marked deprecated and the repository is not archived, but there is no evidence of active direct maintenance or releases for icss-replace-symbols itself.
Ecosystem3/5The package recorded 3,477,764 npm downloads for July 31 through August 6, 2026, showing that it remains deep in frontend dependency trees. Its resolved GitHub repository has only 22 stars and 17 forks, and new ICSS development is centered on icss-utils. The download count therefore reflects compatibility and transitive installation more than a healthy standalone plugin community, tutorials, adapters, or new direct adoption.

Use it if

  • You maintain an older PostCSS or CSS Modules plugin that already imports this exact package
  • You need to replace ICSS tokens in declaration values and @media parameters while leaving selectors and property names alone
  • You receive a PostCSS tree from another tool and want a synchronous mutation with no runtime dependencies
  • You need behavior compatible with the historical CSS Modules linking implementation
Skip it if

Setup reality

Installation is only npm install icss-replace-symbols, and the package has no runtime dependencies, native build, credentials, configuration file, or peer dependency declaration. That simplicity hides the main integration work: it does not parse CSS for you. Your code must already have a PostCSS Root with walkDecls and walkAtRules methods, then call the function during the linking phase. The README uses Babel-style default-import syntax. The published file is CommonJS compiled by Babel, so require('icss-replace-symbols') returns an object and CommonJS callers need .default. The function mutates the supplied tree in place and returns undefined. Replacements happen only in declaration values and parameters of @media rules; selectors, declaration property names, and other at-rules are untouched. Token matching is lexical rather than CSS-value-aware: the regular expression recognizes word characters plus $, #, hyphen, and dot, which permits keys such as --brand, #f00, and 0.5em but also means dotted tokens are considered whole symbols. Replacement values are not recursively reprocessed in the same match. There are no bundled TypeScript types, no documented error model, and no modern PostCSS peer range to tell package managers whether your version is supported. In a new plugin, install icss-utils and import replaceSymbols from there instead; this package mainly makes sense when preserving an existing dependency graph.

Patterns

Replace a token in declaration valuesreplace-declaration-token

import postcss from 'postcss';
import replaceSymbols from 'icss-replace-symbols';

const root = postcss.parse('.button { color: brandColor }');
replaceSymbols(root, { brandColor: '#2563eb' });
console.log(root.toString());

The root is mutated in place; replaceSymbols does not return the transformed CSS.

Replace several tokens in one valuereplace-multiple-values

const root = postcss.parse('.card { box-shadow: x y blur spread shadowColor }');
replaceSymbols(root, {
  x: '0',
  y: '2px',
  blur: '8px',
  spread: '0',
  shadowColor: 'rgb(0 0 0 / 20%)',
});
console.log(root.toString());

Every matching token in the declaration value is handled in the same synchronous tree walk.

Expand a token in a media queryreplace-media-token

const root = postcss.parse('@media small { .grid { display: grid } }');
replaceSymbols(root, { small: '(max-width: 599px)' });
console.log(root.toString());

Only @media parameters are visited. Tokens in @supports, @container, and other at-rules are not replaced.

Rename a custom property referencerewrite-custom-property-reference

const root = postcss.parse('.alert { color: var(--danger) }');
replaceSymbols(root, { '--danger': '--color-error' });
console.log(root.toString());

This changes the reference inside the value, not the custom-property declaration name itself.

Wrap it for a PostCSS processorwrap-postcss-plugin

const translations = { gapToken: '1rem' };
const icssLinker = {
  postcssPlugin: 'local-icss-linker',
  Once(root) {
    replaceSymbols(root, translations);
  },
};

const result = await postcss([icssLinker]).process(
  '.stack { gap: gapToken }',
  { from: undefined },
);

The package export is a tree helper, not a PostCSS 8 plugin object, so it needs this adapter when used in a processor list.

Load the default export from CommonJSuse-commonjs

const postcss = require('postcss');
const replaceSymbols = require('icss-replace-symbols').default;

const root = postcss.parse('.badge { background: accent }');
replaceSymbols(root, { accent: 'tomato' });

The published Babel-generated CommonJS module does not assign the function directly to module.exports; .default is required.

Limit replacements to valuespreserve-selectors-and-properties

const root = postcss.parse('.brand { brand: brand }');
replaceSymbols(root, { brand: 'renamed' });
console.log(root.toString());
// .brand { brand: renamed }

The class selector and property name remain unchanged because the implementation walks declaration values, not the whole CSS text.

Replace hash and dimension tokensreplace-literal-css-tokens

const root = postcss.parse('.box { border: 1px solid #f00; margin: 0.5em }');
replaceSymbols(root, { '#f00': 'rebeccapurple', '0.5em': '8px' });
console.log(root.toString());

The matcher accepts #, $, hyphen, dot, and word characters, so keys are not limited to JavaScript-style identifiers.

Account for dotted tokensavoid-partial-dotted-token

const root = postcss.parse('.item { color: palette.red; background: red }');
replaceSymbols(root, { red: 'green' });
console.log(root.toString());
// .item { color: palette.red; background: green }

Dots are part of a matched symbol. A mapping for red does not replace the red portion of palette.red.

Use one-pass replacement semanticsavoid-recursive-replacement

const root = postcss.parse('.item { color: primary; background: secondary }');
replaceSymbols(root, { primary: 'secondary', secondary: 'black' });
console.log(root.toString());
// .item { color: secondary; background: black }

Inserted replacement text is not processed again at the same position, so mapping order does not create a replacement chain.

Alternatives

PackageRegistryPick it when
icss-utilsnpmNew ICSS tooling that needs the current replaceSymbols export plus import and export extraction helpers
postcss-modules-valuesnpmYou want a complete PostCSS plugin for defining and importing values between CSS Modules files
postcss-modulesnpmYou need the whole CSS Modules transformation pipeline rather than a low-level token mutator
postcss-custom-propertiesnpmYour values are standard CSS custom properties and should be transformed through a maintained PostCSS plugin