Skip to content

Selectors

Selectors determine which nodes a rule or query targets. They can be used as the is key in a rule, or passed to select functions.

Match nodes that have a specific trait in their expanded is list:

nest.host # single trait
nest.admin # marker trait

A list of selectors — all must match:

[ nest.host nest.web ] # has both host AND web
[ nest.host (nest.has nest.admin) ] # host AND has admin child
[ nest.host (nest.attrs { env = "prod"; }) ] # host AND env=prod attribute

A CSS selector string — parsed at evaluation time:

"*" # star
"#lb-prod" # by name
".nixos" # by entity class
"[env=prod]" # attribute equality
"[system]" # attribute presence
"web, lb" # or (comma)
"prod > web" # child combinator
"prod web" # descendant combinator (space-separated — uses +)
":not(.staging)" # negation
":has(.admin)" # has child
":within(.prod)" # within ancestor

See CSS Syntax for full string selector syntax.


All constructors are available as nest.<name> inside rules and the nest module.

Matches any node:

nest.star

Matches nodes where all listed attributes equal their expected values:

nest.attrs { env = "prod"; }
nest.attrs { env = "staging"; system = "aarch64-linux"; }

Uses builtins.toString for comparison — works with strings, booleans, and integers.

Matches nodes that satisfy at least one selector in the list:

nest.or [ nest.web nest.lb ]
nest.or [ (nest.attrs { env = "prod"; }) (nest.attrs { env = "staging"; }) ]

Matches nodes that do NOT match sel. sel may be a list (which is AND):

nest.not nest.staging
nest.not [ nest.host nest.staging ]

Matches nodes that have at least one direct child matching sel:

nest.has nest.admin # host has a child with admin trait
nest.has nest.user # node has at least one user child

Matches nodes that have at least one ancestor matching sel:

nest.within nest.host # node is nested somewhere under a host
nest.within "prod" # node is nested under a node named prod

Matches nodes for which fn returns true. The function receives the same args as a rule function:

nest.when ({ host, ... }: host.httpPort > 1024)
nest.when ({ select, ... }: select.node.env == "prod")
nest.when ({ select, ... }: builtins.length (select.children nest.user) > 0)

Matches nodes whose entity trait exposes a class with the given name:

nest.class "nixos" # entity produces nixosSystem output
nest.class "homeManager" # entity produces homeManager output

Matches nodes that satisfy childSel AND whose direct parent satisfies parentSel:

nest.child nest.cluster nest.web
nest.child "#prod" nest.host

Equivalent to CSS prod > web.

Matches nodes that satisfy descendantSel AND have some ancestor satisfying ancestorSel:

nest.descendant nest.cluster nest.web
nest.descendant "#prod" nest.host

Equivalent to CSS descendant combinator.


nest.rules = [
{ is = nest.host; nixos = ; }
{ is = [ nest.host (nest.has nest.admin) ]; nixos = ; }
{ is = "*.web"; nixos = ; }
];
# Inside a rule or synth function:
select nest.web # filter allNodes by nest.web
select.siblings nest.host # filter siblings by trait
select.children nest.user # filter direct children by trait
select.parent nest.cluster # filter direct parent
select.parents nest.host # filter all ancestors matching
select.within clusterNode nest.web # descendants of clusterNode matching

See Select API for the full context API.


A node matches a selector if:

Selector typeMatch condition
Trait__traitName appears in any item of node.is
ListAll selectors in the list match
StringParsed as CSS, then matched
starAlways true
id / namenode.name == sel.name
attrtoString node.key == sel.val
attrExistsnode ? key
attrsAll key-value pairs match
orAny selector in list matches
notNo selector in list matches
hasAny direct child matches inner selector
withinAny ancestor matches inner selector
whenPredicate function returns true
classEntity trait has a class with this name
childNode matches childSel AND parent matches parentSel
descendantNode matches descendantSel AND some ancestor matches ancestorSel
Contribute Community Sponsor