Join our Newsletter — 33% off our NHI Course

What is the difference between structural pattern matching and typed metavariables in Semgrep?

Structural pattern matching looks for code shapes, while typed metavariables add type constraints to those shapes. That extra constraint lets a rule match only when a captured value has a specific type, which filters out irrelevant matches. The result is the same basic search model, but with much better precision for security and quality checks.

Why This Matters for Security Teams

Semgrep is often used to turn secure coding policy into something enforceable at review time, so the difference between general structural pattern matching and typed metavariables is really about signal quality. Structural matching is broad and fast, but it can overmatch when the same code shape appears in both safe and unsafe contexts. Typed metavariables narrow the search to values with a specific type, which is especially useful when a rule would otherwise flag benign code paths. That makes them a practical precision control for static analysis rather than a different scanning model. For teams building security and quality rules, the choice affects whether a rule is noisy enough to be ignored or precise enough to trust. In practice, many teams only discover that distinction after a rule has already produced too many false positives in review.

How It Works in Practice

Structural pattern matching in Semgrep looks for syntactic shapes in source code. It is useful when the security or correctness issue is visible from the form of the code itself, such as a dangerous API call, an insecure conditional, or a risky data flow pattern. The engine does not need to understand the deeper semantics of the code to find a match. That is what makes it lightweight and broadly applicable.

Typed metavariables add an extra constraint to the match. Instead of saying only “capture this expression,” you also say “capture this expression only if it has this type.” That changes the rule from shape-based matching to shape plus type-based matching. The practical effect is that the same pattern can ignore unrelated objects, helper wrappers, or similarly named values that happen to fit the syntax but not the intended type.

  • Use structural matching when the dangerous shape is enough to identify the issue.
  • Use typed metavariables when the rule needs to distinguish between similar-looking expressions with different semantic meaning.
  • Expect better precision when the type system is reliable and the codebase uses consistent annotations.
  • Expect weaker results when type information is incomplete, inferred inconsistently, or obscured by dynamic language patterns.

For security checks, this matters because a broad rule may be correct in principle but too noisy to keep enabled. Typed metavariables help preserve the intent of the rule while reducing irrelevant matches. These controls tend to break down when the language or build pipeline does not provide dependable type information, because the rule can no longer separate the intended target from a syntactically similar decoy.

Common Variations and Edge Cases

Tighter matching often increases rule complexity and maintenance overhead, so teams need to balance precision against authoring effort. A typed metavariable is not always the best choice if the type signal is unstable or if the rule should intentionally catch multiple related types.

One common edge case is code that is polymorphic, dynamically typed, or only partially annotated. In those environments, a typed metavariable may miss real issues because the type is unavailable at analysis time. Another is when the same unsafe pattern can appear across multiple types, in which case an overly narrow type constraint can create blind spots. In those cases, current guidance suggests starting with a structural rule, then adding type constraints only where the false-positive rate justifies the extra specificity.

Another practical nuance is that typed metavariables are most valuable when the rule author already understands the API surface being checked. If the goal is broad discovery during triage, structural matching may be the better first pass. If the goal is a durable policy rule that should stay enabled in CI, type constraints usually earn their keep by improving reviewer trust.

Practitioner Guidance

What to prioritise: Start with the least restrictive rule that still reflects the security intent. If a purely structural pattern produces noisy results, add a type constraint only where the false positives are caused by semantically different objects sharing the same syntax.

What to verify: Confirm that the type information Semgrep will see is actually present in the codebase and build context. If your analysis environment cannot reliably resolve types, treat typed metavariables as a precision aid, not as a guaranteed filter.

Practitioner takeaway: Structural matching finds the shape of a problem, while typed metavariables decide whether that shape is the right kind of problem; the best rules use type constraints to remove noise without hiding real risk.