Sass meta.variable-exists() Function

Beginner
⏱️ 11 min read
📚 Updated: Jul 2026
🎯 5 Examples
sass:meta · current scope

What You’ll Learn

meta.variable-exists() belongs to the built-in sass:meta module. It answers: is there a variable named X in the current scope? This page covers the no-$ name rule, locals vs globals, vs meta.global-variable-exists, and five compiled examples.

01

Concept

Is this name in scope?

02

Module

@use "sass:meta"

03

Returns

true / false

04

Name

Without the $

05

vs global

Locals count here

06

Practice

5 examples

What Is meta.variable-exists()?

Official docs: returns whether a variable named $name (without the $) exists in the current scope. That includes globals you can see from here and locals declared in the current rule, mixin, or function.

  • Pass the bare name: "var1" checks $var1.
  • Missing names return false—they do not throw.
  • There is no $module argument (unlike global-variable-exists).
  • See also meta.global-variable-exists() when you only want file-level globals.
💡
Beginner tip

Think of looking around the room you are in: variable-exists finds the desk lamp (local) and the hallway light you can still see (global). global-variable-exists only asks about the hallway.

📝 Syntax

styles.scss
@use "sass:meta";

// Recommended
meta.variable-exists($name)

// Legacy global name
variable-exists($name)

Parameters

ParameterTypeRequiredDescription
$nameStringYesVariable name to look up without the leading $.

Return value

TypeResult
Booleantrue if the variable exists in the current scope; otherwise false

📦 Loading sass:meta

styles.scss
// Recommended — namespaced
@use "sass:meta";
$ok: meta.variable-exists("brand");

// Optional — bring members into scope
@use "sass:meta" as *;
$ok: variable-exists("brand");

// Legacy global
$ok: variable-exists("brand");

🏢 Locals vs Globals

Official sample: a root $var1 is global; a $var2 inside h1 { … } is local. variable-exists finds both when you ask from a scope that can see them.

Where definedvariable-existsglobal-variable-exists
File root (global)true (from scopes that see it)true
Inside a rule / mixin / function (local)true (in that scope)false
Never definedfalsefalse

📋 Related Meta Helpers

HelperChecksReturns
meta.variable-existsCurrent scope (local + global)Boolean
meta.global-variable-existsGlobals only (+ optional $module)Boolean
meta.module-variablesAll variables in a @use moduleMap of values
meta.function-existsFunctionsBoolean
meta.mixin-existsMixinsBoolean

🛠 Compatibility

This is about Sass compilers, not browsers. The lookup runs at compile time.

Implementationvariable-exists
Dart SassYes — prefer meta.variable-exists
LibSassYes (legacy global)
Ruby SassYes (legacy global)

Prefer current Dart Sass and the namespaced meta.* API.

⚡ Quick Reference

GoalCode
Import meta@use "sass:meta";
Check current scopemeta.variable-exists("brand")
Optional valueif(meta.variable-exists("brand"), $brand, $fallback)
Globals onlymeta.global-variable-exists("brand")
Wrong (includes $)meta.variable-exists("$brand") — do not pass $

Examples Gallery

Each example uses meta.variable-exists at compile time. Open View Compiled CSS for verified Dart Sass output.

📚 Getting Started

Official-style before/after checks and local scope.

Example 1 — Before and After Defining a Variable

A name is missing until you define it (official var1 idea).

styles.scss
@use "sass:meta";

.before {
  --var1: #{meta.variable-exists("var1")};
}

$var1: value;

.after {
  --var1: #{meta.variable-exists("var1")};
}

How It Works

Matches the official docs idea: var1 is false until $var1 is defined, then true.

Example 2 — Locals Count in the Current Scope

A variable inside a rule is visible to variable-exists there.

styles.scss
@use "sass:meta";

$brand: #0d9488;

.card {
  $accent: #f59e0b;
  --brand: #{meta.variable-exists("brand")};
  --accent: #{meta.variable-exists("accent")};
  --missing: #{meta.variable-exists("nope")};
}

How It Works

From inside .card, both the global $brand and the local $accent exist. nope does not.

📈 Practical Patterns

Compare helpers, optional defaults, and mixin scope.

Example 3 — vs global-variable-exists

Same names, different answers for a local variable.

styles.scss
@use "sass:meta";

$brand: #0d9488;

.card {
  $accent: #f59e0b;
  --accent-any: #{meta.variable-exists("accent")};
  --accent-global: #{meta.global-variable-exists("accent")};
  --brand-any: #{meta.variable-exists("brand")};
  --brand-global: #{meta.global-variable-exists("brand")};
}

How It Works

Local $accent is found by variable-exists only. Global $brand is found by both helpers.

Example 4 — Optional Values with if()

Use a variable when it exists; otherwise fall back.

styles.scss
@use "sass:meta";

$brand: teal;

.box {
  color: if(meta.variable-exists("brand"), $brand, gray);
  border-color: if(meta.variable-exists("accent"), $accent, silver);
}

How It Works

$brand exists, so color is teal. $accent does not, so the false branch of if() supplies silver without reading a missing variable.

Example 5 — Locals Inside a Mixin

A mixin-local variable is visible to nested rules in that mixin.

styles.scss
@use "sass:meta";

@mixin chip {
  $label: "chip";
  .chip {
    --has-label: #{meta.variable-exists("label")};
    --has-ghost: #{meta.variable-exists("ghost")};
    content: $label;
  }
}

@include chip;

How It Works

$label lives in the mixin scope and is seen from .chip. ghost was never defined.

🚀 Real-World Use Cases

  • Optional theme hooks — use $brand only when the caller defined it.
  • Local overrides — detect a rule-level $accent without requiring a global.
  • Safer if() defaults — avoid reading names that might not exist.
  • Mixin internals — branch on locals created inside the mixin.
  • Migration aid — pair with global-variable-exists to understand scope bugs.

🧠 How Compilation Works

1

Pass a bare name

Call meta.variable-exists("brand") (no $).

Source
2

Sass searches this scope

Looks at locals and reachable globals from the current location.

Compile
3

Boolean drives if() / @if

Your stylesheet keeps or skips optional variable paths.

Branch
4

CSS ships

Browsers never see meta.variable-exists—only finished values.

⚠️ Common Pitfalls

  • Including $ in the name — check "brand", not "$brand".
  • Wrong helper for globals-only — use global-variable-exists when locals must not count.
  • Expecting $module — this function has no module argument.
  • Reading the variable before the guard — use if() so the missing branch never evaluates $missing.
  • Expecting runtime checks — everything resolves when Sass compiles.

💡 Best Practices

✅ Do

  • Use @use "sass:meta" and meta.variable-exists()
  • Pass names without $
  • Use this when locals should count
  • Pair with lazy if() for optional values
  • Prefer Dart Sass + the namespaced API

❌ Don’t

  • Pass "$name" with a dollar sign
  • Assume it only finds globals
  • Expect a $module parameter
  • Reference a missing variable outside a guarded if()
  • Expect the browser to evaluate the check

Key Takeaways

Knowledge Unlocked

Five things to remember about meta.variable-exists()

Ask whether a variable name exists in the current scope—locals included.

5
Core concepts
📦 02

Module

sass:meta

@use
03

Returns

boolean

Result
🔗 04

Name

without $

Detail
05

Scope

locals + globals

Key

❓ Frequently Asked Questions

meta.variable-exists($name) returns true if a variable named $name exists in the current scope, otherwise false. Pass the name without the $.
No. Official docs use the bare name: meta.variable-exists("var1") checks $var1.
variable-exists finds locals and globals in the current scope. global-variable-exists only finds globals—a variable declared inside a rule is local, so global-variable-exists is false while variable-exists is true.
No. Unlike global-variable-exists, variable-exists only takes $name and checks the current scope.
Yes. variable-exists($name) is the legacy global name. Prefer meta.variable-exists after @use "sass:meta".
No. It runs at compile time. Browsers only see the CSS after your @if / if() branches resolve.
Did you know?

Official Sass docs point from variable-exists to global-variable-exists on purpose: one question is “can I see this name here?” and the other is “is it a true global?”—easy to mix up when debugging scope.

Conclusion

meta.variable-exists() returns whether a named variable exists in the current scope. Pass the name without $, remember locals count, and switch to meta.global-variable-exists when you only want file-level globals.

Continue with selector.append() or the Sass introduction.

Next: append selectors

Learn selector.append() to glue selectors without descendant spaces.

selector.append() →

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