Introducing the new npm Dependency Selector Syntax

npm query is a new top-level command as of npm v8.16.0 which accepts a Dependency Selector (as defined in the Dependency Selector Syntax Specification) & returns a filtered JSON Array/NodeList of dependencies from your project. We believe this capability has been a missing piece of the package management ecosystem; With its introduction we hope to unlock the potential for developers to self-serve in asking new, complex questions about their dependencies, their relationships & associative metadata.

For many JavaScript developers, the Dependency Selector Syntax will look very familiar as it is actually an adapted form of CSS. We leveraged this existing, known language & its operators to make disparate package information broadly accessible.

Example Uses:

If I wanted to list all of my dependencies (similar to npm list --all) I can run:

npm query "*"

If I wanted to find every version of react & lodash in my project I can run:

npm query "#react, #lodash"

If I wanted to find all react versions not-defined as a peer dependency I can run:

npm query "#react:not(.peer)"

If I wanted to find all the dependencies in my project that used an MIT license I'd change that query to be:

npm query "[license=MIT]"

If I wanted to find all the git dependencies in my project I can run:

npm query ":type(git)"

If I wanted to find out which of my transitive dependencies used a postinstall script I could run:

npm query ":attr(scripts, [postinstall]):not(:root > *)"

Programmatic Usage

We know many developers in the ecosystem will also want to leverage this new syntax themselves, so we've built it right into the programmatic brain of the CLI. Under the hood, we’ve added a new .querySelectorAll() method to the existing Node Class we use in the @npmcli/arborist library. Tooling authors can now load up & query their dependencies just like we do.

// index.js
const Arborist = require('@npmcli/arborist')
const arb = new Arborist({})

arb.loadActual((tree) => {
  // query all workspaces
  const results = await tree.querySelectorAll('.workspace')
  console.log(results)
})

You can learn more about the syntax & usage in our documentation here: https://docs.npmjs.org/cli/v8/using-npm/dependency-selectors

What's next?

Looking ahead we’ve got work planned to add new pseudo states & selectors based on registry metadata that should unlock another host of capabilities aimed at auditing (examples include: :outdated :deprecated :vulnerable :cve() & :cwe()). As documented in the original RFC proposal we will also consider supporting a query flag or reading from stdin to existing commands.

Previously we retained self-hosted GitHub Action runners in the GitHub Actions UI for 30 days after they were last seen to connect. With the growth in the use of ephemeral runners and the scale of use of self-hosted, this is becoming hard for users to manage. As a result, we are making the following changes to the time we retain offline runners for.

A non-ephemeral self-hosted Actions runner is automatically removed from GitHub if we have not seen it connect to GitHub for more than 14 days.

An ephemeral self-hosted Actions runner is automatically removed from GitHub if we have not seen it connect to GitHub for more than one day.

Learn more about self-hosted runners in GitHub Actions

For questions, visit the GitHub Actions community

To see what's next for Actions, visit our public roadmap

See more

[August 2, 2022] Update: In order to better reach and improve the web experience for enterprise users, we are adding non-essential web cookies to certain subdomains that specifically market our products to businesses. These cookies will provide analytics to help us improve and deliver a better site experience for our enterprise customers, and enable us to further our support for enterprises through personalized content and marketing around our enterprise solutions.

The developer community remains the heart of GitHub, and we’re committed to respecting the privacy of developers using our product. We also recognize that we need to improve the developer experience for enterprise users and make it easier for businesses to find our enterprise solutions. This change is only on subdomains where GitHub markets products and services to enterprise customers, and all other GitHub subdomains will continue to operate as-is. 

You can learn more and give feedback on our privacy policy here for the next 30 days, after which the change will go into effect.

See more