Sass map.set() Function

Beginner
⏱️ 12 min read
📚 Updated: Jul 2026
🎯 5 Examples
sass:map · Dart Sass

What You’ll Learn

map.set() belongs to the built-in sass:map module. It returns a new map with one key written (added or updated). This page covers nested path updates, missing path segments, immutability, vs map.merge, and five compiled examples.

01

Concept

Write one key

02

Module

@use "sass:map"

03

Add / update

Same call

04

Nested path

Dart Sass 1.27+

05

vs merge

One key vs many

06

Practice

5 examples

What Is map.set()?

Sass maps are immutable. You cannot assign into a map like $map["primary"] = #fff. Instead, map.set() builds a new map with one key written:

  • If the key is new, it is added
  • If the key already exists, its value is replaced
  • All other keys are copied as they were

With Dart Sass 1.27+, you can pass a path of keys to update a nested value without rebuilding the whole tree by hand.

💡
Beginner tip

Think of rewriting one line on a sticky note and getting a fresh copy. The old note stays the same until you reassign: $map: map.set($map, $key, $value);

📝 Syntax

Load the map module, then call the function:

styles.scss
@use "sass:map";

// Top-level key
map.set($map, $key, $value)

// Nested path (Dart Sass 1.27+)
map.set($map, $keys..., $key, $value)

Parameters

ParameterTypeRequiredDescription
$mapMapYesSource map. Never mutated—you always get a new map back.
$keys...KeysNoOptional path into nested maps (Dart Sass 1.27+). Omitted for a top-level set.
$keyAnyYesThe key to write in the targeted map (last key before the value).
$valueAnyYesThe value stored at $key.
⚠️
Argument naming note

Official docs describe nested calls as map.set($map, $keys..., $key, $value) for clarity. In practice Sass receives them as map.set($map, $args...)—the last argument is the value, and the one before it is the key being set.

Return value

TypeSituationResult
MapNo path keysCopy of $map with top-level $key set to $value
MapWith path keysCopy of $map where the nested target has $key set to $value

📦 Loading sass:map

map.set lives in the map module. There is no legacy global map-set()—always load sass:map.

styles.scss
// Recommended — namespaced
@use "sass:map";
$tokens: map.set($tokens, "primary", #1d4ed8);

// Optional — bring members into the current namespace
@use "sass:map" as *;
$tokens: set($tokens, "primary", #1d4ed8);

// Optional — custom namespace
@use "sass:map" as m;
$tokens: m.set($tokens, "primary", #1d4ed8);
⚠️
Put @use first

@use rules must appear before most other rules. Keep @use "sass:map"; near the top of the file.

🔢 Add vs Update

The same call handles both cases. Sass does not care whether the key already existed.

styles.scss
@use "sass:map";

$weights: ("regular": 400, "bold": 700);

// Update an existing key
map.set($weights, "regular", 300);
// ("regular": 300, "bold": 700)

// Add a new key
map.set($weights, "medium", 500);
// ("regular": 400, "bold": 700, "medium": 500)

🔗 Nested Path Set

With Dart Sass 1.27+, pass keys before the final key/value to update a nested map. If a key along the path is missing or not a map, Sass stores an empty map there so the path can continue.

styles.scss
@use "sass:map";

$fonts: (
  "Helvetica": (
    "weights": (
      "regular": 400,
      "medium": 500,
      "bold": 700
    )
  )
);

map.set($fonts, "Helvetica", "weights", "regular", 300);
// Helvetica → weights → regular is now 300
💡
Path set vs merge

Nested map.set writes one leaf. Nested map.merge overlays a whole map onto a nested target. Pick set for a single token; pick merge for many keys at that location.

📋 map.set vs map.merge

map.setmap.merge
WritesOne key (or one nested leaf)All keys from an overlay map
Best forSingle token updatesLayering defaults + overrides
Nested formPath + final key/valuePath + overlay map
Legacy globalNonemap-merge

🛠 Compatibility

This is about Sass compilers, not browsers. Compiled CSS only contains the finished values you read from the updated map (for example with map.get).

Implementationmap.set() (2–3 args)Nested path set
Dart Sass (1.23+)Yes — preferred1.27+ only
LibSassNo modern sass:map APINo
Ruby SassNo modern sass:map APINo

Prefer Dart Sass for new work. Use current Dart Sass (1.27+) for nested path updates.

⚡ Quick Reference

GoalCode
Import map@use "sass:map";
Set top-level keymap.set($map, "primary", #1d4ed8)
Set nested leafmap.set($map, "a", "b", "c", $value)
Keep result$map: map.set($map, $key, $value);
Read after setmap.get($map, $key)
Many keys at oncemap.merge($map, $overlay)

Examples Gallery

Each example uses @use "sass:map". Open View Compiled CSS to see what Dart Sass emits (maps inspected via meta.inspect where needed).

📚 Getting Started

Official docs sample plus adding a brand-new key.

Example 1 — Update a Top-Level Key (Official Docs)

Change regular from 400 to 300.

styles.scss
@use "sass:map";
@use "sass:meta";

$font-weights: ("regular": 400, "medium": 500, "bold": 700);

@debug map.set($font-weights, "regular", 300);
// ("regular": 300, "medium": 500, "bold": 700)

.weights {
  --updated: #{meta.inspect(map.set($font-weights, "regular", 300))};
}

How It Works

Sass copies the map and replaces the value at "regular". $font-weights itself is unchanged unless you reassign.

Example 2 — Add a New Key

Writing a key that does not exist appends it to the map.

styles.scss
@use "sass:map";

$palette: (
  "primary": #336699,
  "muted": #94a3b8
);
$palette: map.set($palette, "accent", #e67e22);

.btn {
  color: map.get($palette, "primary");
  outline-color: map.get($palette, "accent");
}

How It Works

Reassignment stores the new map so later map.get calls see "accent".

📈 Practical Patterns

Nested updates, theme tokens, and creating missing path segments.

Example 3 — Nested Path Set (Official Docs)

Walk into Helvetica → weights and update regular.

styles.scss
@use "sass:map";
@use "sass:meta";

$fonts: (
  "Helvetica": (
    "weights": (
      "regular": 400,
      "medium": 500,
      "bold": 700
    )
  )
);
$updated: map.set($fonts, "Helvetica", "weights", "regular", 300);

.font {
  --regular: #{map.get($updated, "Helvetica", "weights", "regular")};
  --weights: #{meta.inspect(map.get($updated, "Helvetica", "weights"))};
}

How It Works

Path keys locate the nested map; only "regular" changes. Sibling weights stay intact.

Example 4 — Theme Token Patch

Override one brand color, then emit CSS variables from the result.

styles.scss
@use "sass:map";

$theme: (
  "primary": #336699,
  "radius": 8px,
  "gap": 16px
);
$theme: map.set($theme, "primary", #1d4ed8);

.card {
  --primary: #{map.get($theme, "primary")};
  --radius: #{map.get($theme, "radius")};
  --gap: #{map.get($theme, "gap")};
}

How It Works

Only primary changes. Other tokens keep their original values through the copy.

Example 5 — Create Missing Nested Path

If a path segment is missing, Sass inserts an empty map there, then sets the final key.

styles.scss
@use "sass:map";
@use "sass:meta";

$config: ("meta": ("name": "app"));
$built: map.set($config, "theme", "colors", "primary", #1d4ed8);

.demo {
  --built: #{meta.inspect($built)};
  --primary: #{map.get($built, "theme", "colors", "primary")};
}

How It Works

"theme" and "colors" did not exist, so Sass created nested maps for them, then stored "primary". Existing "meta" is preserved.

🚀 Real-World Use Cases

  • Single token patches — change one color, radius, or weight without rebuilding the map.
  • Nested design systems — update brand → colors → primary with a path set.
  • Mixin APIs — accept a user key/value and write it onto defaults.
  • Incremental builders — grow a config map step by step during compilation.
  • Safe path creation — let missing segments become empty maps when scaffolding tokens.

🧠 How Compilation Works

1

Write SCSS

Call map.set($map, $key, $value) after @use "sass:map".

Source
2

Copy & write

Dart Sass copies the map (and nested targets) and stores the new value.

Compile
3

New map returned

Reassign if needed, then read with map.get.

Result
4

CSS sees values

Browsers never see map.set—only the finished CSS you emit.

⚠️ Common Pitfalls

  • Forgetting to reassignmap.set returns a copy; originals stay unless you assign the result.
  • Wrong argument order — the last argument is always the value; the one before it is the key being set.
  • Expecting a global map-set — there is none; load sass:map.
  • Nested path on old Sass — more than three arguments needs Dart Sass 1.27+.
  • Using set for many keys — prefer map.merge when overlaying a whole map of updates.

💡 Best Practices

✅ Do

  • Use @use "sass:map" and map.set() in new SCSS
  • Reassign when updating a stored config variable
  • Use nested paths for leaf tokens in design-system maps
  • Prefer map.merge when writing many keys at once
  • Prefer Dart Sass 1.27+ for nested path set

❌ Don’t

  • Expect the browser to evaluate map.set
  • Assume originals mutate without reassignment
  • Look for a legacy global map-set()
  • Chain many single sets when one merge would be clearer
  • Rely on LibSass for the modern map module API

Key Takeaways

Knowledge Unlocked

Five things to remember about map.set()

Write one key—returns a new map; nested paths need Dart Sass 1.27+.

5
Core concepts
📦 02

Module

sass:map only

@use
03

Effect

add or update

Rule
🔗 04

Nested

path + leaf value

Safe
05

Immutable

reassign to keep

Tooling

❓ Frequently Asked Questions

map.set($map, $key, $value) returns a new map with $key set to $value. If the key already exists, its value is replaced. Extra keys before the final key/value (Dart Sass 1.27+) update a nested map along that path.
No. It returns a copy. Reassign if you need to keep the result: $tokens: map.set($tokens, "primary", #1d4ed8).
Yes on Dart Sass 1.27+: map.set($map, "a", "b", "c", $value) walks a → b and sets c to $value. Missing keys along the path become empty maps.
map.set updates one key (or one nested leaf). map.merge combines two whole maps. Use set for a single write; use merge when overlaying many keys at once.
No. Unlike map-get or map-remove, map.set is module-only. Load it with @use "sass:map" (or @use "sass:map" as * and call set()).
Official docs: if any key in the path is missing or points to a non-map, Sass sets that key to an empty map so the path can continue, then applies the final set.
Did you know?

Official Sass docs use the same Helvetica nested weights sample for map.get, map.set, map.merge, and the deep helpers—so you can compare read, write, and merge patterns on one familiar map shape.

Conclusion

map.set() is the everyday write helper for Sass maps: one key, one value, a new map returned. Use nested paths on Dart Sass 1.27+ for design-system leaves, reassign to keep results, and reach for map.merge when many keys change together.

Continue with map.values() or the Sass introduction.

Next: list map values

Learn map.values() to turn a map into a list of stored data.

map.values() →

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.

5 people found this page helpful