The :attr() pseudo-class selects packages based on nested
properties of their package.json metadata. While
attribute selectors match
top-level fields, :attr() lets you drill into nested objects.
Syntax
:attr(key, [attr=value]):attr(key, nestedKey, [attr=value])Arguments are a path of property keys, ending with a standard attribute selector.
Examples
Optional peer dependencies
Select packages that declare foo as an optional peer dependency:
$ vlt query ':attr(peerDependenciesMeta, foo, [optional=true])'This is equivalent to checking:
{ "peerDependenciesMeta": { "foo": { "optional": true } }}Engine requirements
Select packages that have a node engine requirement:
$ vlt query ':attr(engines, [node])'Scripts
Select packages that have a build script:
$ vlt query ':attr(scripts, [build])'Select packages that have a test script using vitest:
$ vlt query ':attr(scripts, [test*=vitest])'What gets selected
Given this dependency graph:
my-app├── react@18.2.0│ └── loose-envify@1.4.0 ← has scripts.postinstall├── typescript@5.3.0 ← has engines.node└── vite@5.0.0 ← has engines.nodeThe query :attr(engines, [node]) selects:
my-app├── react@18.2.0│ └── loose-envify@1.4.0├── typescript@5.3.0 ✅ has engines.node└── vite@5.0.0 ✅ has engines.nodeCombining with combinators
Find direct dependencies that have a build script:
$ vlt query ':project > :attr(scripts, [build])'See also
- Attribute Selectors — top-level property matching
:semver()— compare semver values in nested properties