Individual skill
elixir-meta-programming
Use this skill when building an Elixir macro or a declarative DSL — a schema/spec/route/workflow language in the shape of Ecto.Schema, Absinthe, Plug.Router, or ExUnit — with quote/unquote, __using__, module attributes, and @before_compile. It corrects the wrong defaults a model makes once it commits to metaprogramming — putting logic inside the quote block, re-evaluating unquoted expressions, forgetting Macro.escape, fighting hygiene with var!, generating code ad hoc instead of accumulating declarations, and validating the DSL at runtime rather than at compile time. Applies to writing or reviewing macro/DSL code. NOT for deciding whether to use a macro at all — that gate belongs to staff-level-elixir and adversarial-elixir, which say prefer plain functions.
skills/.experimental/elixir-meta-programming/SKILL.md
Source commit cf93c57cac89d6fc3e4194686000411567f5caf3
What was checked
- Matches the observed repository HEAD
- Yes
- Scanner rules are current
- No
- Repository scan complete
- No
- Skill scan complete
- No
- Observed behavior
- Not checked yet
- Last checked
- Nov 5, 2026
These are observations at the recorded commit, not a guarantee of safety. Review the source before running it.
Install this skill
Choose an agent in your Stack or copy a command below. Commands fetch the pinned commit and copy only this skill directory. Existing destinations are refused. Copying a command does not install anything.
An install command is unavailable: current rules, complete repository and skill scans, an eligible behavior level and a permitted license are required.
Repository context
- Repository stars (not skill ratings)
- 222
- Repository last updated
- Aug 15, 2026
- License
- MIT
Observed agent integration: codex
- engineering Derived category
- operations Derived category
- writing Derived category
Files and excerpt
File metadata and permitted, redacted excerpts come from the recorded scan. Source links are pinned to that commit.
Browse files
AGENTS.mddoc · 3,576 bytesSKILL.mdcore · 6,116 bytesSKILL.mdcore · 6,116 bytesassets/templates/_template.mddoc · 1,054 bytesmetadata.jsonasset · 1,151 bytesreferences/_sections.mddoc · 2,202 bytesreferences/dsl-accumulate-attributes.mddoc · 2,044 bytesreferences/dsl-introspection-function.mddoc · 1,442 bytesreferences/dsl-unquote-fragments.mddoc · 1,260 bytesreferences/dsl-using-minimal.mddoc · 1,252 bytesreferences/macro-defguard-for-guards.mddoc · 1,203 bytesreferences/macro-thin-delegate-runtime.mddoc · 1,509 bytesreferences/quote-bind-quoted-single-eval.mddoc · 1,484 bytesreferences/quote-escape-runtime-data.mddoc · 1,242 bytesreferences/quote-rely-on-hygiene.mddoc · 1,558 bytesreferences/valid-fail-at-compile-time.mddoc · 1,425 bytesreferences/valid-locate-errors-at-caller.mddoc · 1,733 bytes
Read excerpt
# Elixir Metaprogramming & DSLs
How to build Elixir macros and declarative DSLs *correctly* — for the case where a macro is genuinely warranted and a plain function won't do. Each rule corrects a specific wrong default a capable model makes once it starts writing `quote`/`unquote`, `__using__`, and `@before_compile`; nothing here restates macro basics the model already knows.
## First: is a macro actually warranted?
The default answer is **no** — reach for a higher-order function, a behaviour, or data-plus-an-interpreter first. That gate is not this skill's job; it lives in the sibling skills and you should apply it before opening this one:
- `staff-level-elixir` → `data-functions-over-macros` (solve it with a function first)
- `adversarial-elixir` → `meta-functions-not-macro-dsl`, `meta-use-is-not-import`, `meta-no-compile-time-coupling`
A macro earns its place only when you need something a function cannot give — new syntax, control over whether/when arguments evaluate, or code that must exist at compile time (compiling a schema, generating clauses from a declaration list). **Once you've crossed that threshold, this skill is how you do it right.**
## When to Apply