Sass map.merge()

Beginner
11 min read
Updated: Nov 2026
5 examples
Dart Sass 1.23+

Definition and Usage

map.merge($map1, $map2) returns a new map with all keys from both maps. Matching keys take $map2’s value (shallow—nested maps are replaced, not recursed). Load it with @use "sass:map" on Dart Sass 1.23+. Legacy global name: map-merge.

Official sample.

map.merge(("lightest": 100, "light": 300), ("medium": 500, "bold": 700)) → ("lightest": 100, "light": 300, "medium": 500, "bold": 700).

Nested path form.

Dart Sass also allows map.merge($map, $keys..., $overlay) to shallow-merge into a nested target. Missing mid-path keys become empty maps along the way.

Need recursive merge?

Use map.deep-merge() when colliding nested maps should combine sibling keys instead of replacing the whole branch.

Syntax

SCSS
@use "sass:map";

map.merge($map1, $map2);
map.merge($map1, $keys..., $map2); // nested path (Dart Sass)

map.merge(
  ("lightest": 100, "light": 300),
  ("medium": 500, "bold": 700)
);
// ("lightest": 100, "light": 300, "medium": 500, "bold": 700)

map.merge($fonts, "Helvetica", "weights", $heavy-weights);

// Legacy global (prefer module form)
// map-merge($map1, $map2);

Pattern: base map + overrides → map.merge → read with map.get. For nested token trees, prefer map.deep-merge or the nested-path form of merge.

Shallow vs Deep

Choose based on whether nested maps should replace or combine:

GoalUse
Combine flat mapsmap.merge($base, $over)
Replace a nested branch wholesalemap.merge($base, $over) when both have the same nested key
Merge into one nested pathmap.merge($map, $keys..., $partial)
Recursively combine nested mapsmap.deep-merge($base, $over)
Conflicting key$map2 value wins
Key order$map1 order kept; new $map2 keys appended
Immutable result.

Original maps stay unchanged. Reassign when you want to keep the merge: $config: map.merge($config, $overrides);

SCSS Examples

Examples target Dart Sass with @use "sass:map". Open View Compiled CSS for verified output (matches official Sass docs samples).

Example 1 — Merge Two Flat Maps (Official Docs)

Combine light and heavy weight tokens into one map.

SCSS
@use "sass:map";
@use "sass:meta";

$light-weights: ("lightest": 100, "light": 300);
$heavy-weights: ("medium": 500, "bold": 700);

$merged: map.merge($light-weights, $heavy-weights);

.flat {
  --result: #{meta.inspect($merged)};
  --bold: #{map.get($merged, "bold")};
}

How It Works

  1. All four keys appear in the result.
  2. $map1 keys keep order; new keys append.
  3. No key collisions in this sample.
  4. Matches the official Sass docs sample.

Example 2 — Merge Into a Nested Path (Official Docs)

Walk to Helvetica → weights, then merge the overlay there.

SCSS
@use "sass:map";

$fonts: (
  "Helvetica": (
    "weights": (
      "lightest": 100,
      "light": 300
    )
  )
);
$heavy-weights: ("medium": 500, "bold": 700);

$merged: map.merge($fonts, "Helvetica", "weights", $heavy-weights);

.nested {
  --light: #{map.get($merged, "Helvetica", "weights", "light")};
  --bold: #{map.get($merged, "Helvetica", "weights", "bold")};
}

How It Works

  1. Keys locate the nested weights map.
  2. Overlay merges into that target only.
  3. Existing light keys survive; heavy keys are added.
  4. Matches the official nested-path sample.

Example 3 — merge vs deep-merge

Shallow merge replaces a colliding nested map entirely.

SCSS
@use "sass:map";
@use "sass:meta";

$a: (colors: (primary: blue, secondary: gray));
$b: (colors: (primary: navy, accent: teal));

.compare {
  --merge: #{meta.inspect(map.merge($a, $b))};
  --deep: #{meta.inspect(map.deep-merge($a, $b))};
}

How It Works

  1. Shallow merge drops secondary with the old colors map.
  2. Deep-merge keeps secondary and adds accent.
  3. Both override primary to navy.
  4. Pick deep-merge for nested theme tokens.

Example 4 — $map2 Wins Conflicts

Shared keys take the second map’s value; new keys append.

SCSS
@use "sass:map";
@use "sass:meta";

$c: (a: 1, b: 2);
$d: (b: 9, c: 3);

.wins {
  --result: #{meta.inspect(map.merge($c, $d))};
  --b: #{map.get(map.merge($c, $d), b)};
}

How It Works

  1. a stays from $map1.
  2. b becomes 9 from $map2.
  3. c is appended from $map2.
  4. Order: existing keys first, then new ones.

Example 5 — Reassign Theme Overrides

Persist a merged config for later reads.

SCSS
@use "sass:map";

$config: (
  button: (pad: 8px, radius: 2px),
  ink: navy
);

$config: map.merge($config, (
  button: (pad: 12px, radius: 6px),
  accent: teal
));

.btn {
  padding: map.get($config, button, pad);
  border-radius: map.get($config, button, radius);
  color: map.get($config, ink);
  --accent: #{map.get($config, accent)};
}

How It Works

  1. Reassignment keeps the merged map in $config.
  2. button is replaced wholesale by the override map.
  3. ink survives from the base map.
  4. accent is appended as a new top-level key.

Edge Cases & Pitfalls

Most merge bugs are expecting deep recursion, or forgetting to reassign.

shallow

Nested maps are replaced

A colliding nested key drops sibling keys from $map1. Use deep-merge or the nested-path form when you need to keep them.

path

Missing path creates empty maps

Official docs: if a mid-path key is missing or not a map, Sass sets that key to an empty map and continues.

assign

Returns a copy

Callers must reassign: $map: map.merge($map, $over);

legacy

Prefer map.merge over map-merge

Global map-merge still works but is deprecated toward Dart Sass 3.0. Use the module API.

Sass Support

Prefer the module form with a current Dart Sass release. Nested multi-key merge needs Dart Sass.

APIStatus
map.merge($map1, $map2)Dart Sass 1.23+ via @use "sass:map"
Nested path mergeDart Sass (multi-argument merge)
Global map-merge()Works; deprecated toward Sass 3.0
Return typeNew map (inputs unchanged)

Compile with the Dart Sass CLI.

Key Takeaways

  • Combines two maps into a new one; $map2 wins conflicts.
  • Shallow by default — nested maps replace, they do not recurse.
  • Nested path form merges an overlay into one branch.
  • Prefer map.merge over deprecated global map-merge.

One line: when two maps must combine shallowly, call map.merge($base, $overrides).

Compile Notes

Practical checklist:

checklist.txt
1. @use "sass:map"
2. Use merge for flat / shallow combines
3. Use deep-merge when nested siblings must survive
4. Nested path: map.merge($map, $k1, $k2, $overlay)
5. Reassign: $map: map.merge($map, $over)

Frequently Asked Questions

map.merge($map1, $map2) returns a new map with all keys from both maps. If both share a key, $map2’s value wins. Nested map values are replaced wholesale—not merged recursively (use map.deep-merge for that).
No. It returns a new map. Reassign if you need to keep the result: $config: map.merge($config, $overrides).
map.merge is shallow: a nested map at a colliding key is replaced entirely by $map2’s value. map.deep-merge recursively merges nested maps so sibling keys inside both branches survive.
Yes. map-merge($map1, $map2) is the older global name, but Dart Sass deprecates global built-ins toward Sass 3.0. Prefer map.merge after @use "sass:map". Nested path merge with extra keys needs Dart Sass and the module API.
Yes on Dart Sass: map.merge($map, $key1, $key2, ..., $overlay) walks the keys, then shallow-merges $overlay into that nested target. Missing mid-path keys become empty maps.
$map2 always wins for that key. Keys that only exist in $map1 keep their values and relative order; new keys from $map2 are appended at the end.

Next: Sass map.remove()

Return a copy of a map without one or more top-level keys.

map.remove() →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

8 people found this page helpful