Getting Started With jq

3 minute read


Using jq cli together with npm

I spend most of my time in the terminal. With Tmux, Zsh and Neovim I can do almost everything I need to do without having to switch my focus between applications. Switching apps or views can slow down my productivity.

JSON is the preferred choice by many tools including HTTP servers and NPM. Dealing with JSON in the command line can be very tiresome without the right tools. Not all tools pretty print JSON to stdout.

jq is a command line JSON processor. It allows you to manipulate and transform JSON with filters. The easiest way to pretty print JSON in the command line is by piping the string to jq. The simplest example is:

cat output.json | jq '.'

NPM saves information in a package.json file. When you npm update it updates packages according to the semver evaluation. Most of the time I just want to update to @latest. We could always just iterate over the package.json file and install the latest version of all packages, but that would take the fun out of it.

npm outdated displays a list of outdated packages. The default output of npm is in a table which is not a format that jq can process. Fortunately npm cli has a -json flag which can be added to any to command. This allows us to manipulate the output with jq. We can take that output and transform it with jq and create a list of packages which we can install.

npm outdated -json gives us:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
{
  "tailwindcss": {
    "current": "2.0.2",
    "wanted": "2.0.2",
    "latest": "2.0.3",
    // ...
  },
  "typescript": {
     "current": "4.1.3",
     "wanted": "4.1.3",
     "latest": "4.2.2",
      // ...
  }
}

Let’s skip to the final command and then we can go over each filter and examine what the data looks like. Here is the command to update all outdated packages to the latest version:

 npm install $(
    npm outdated -json | jq --raw-output '. | keys | map(.+"@latest") | join(" ")'
 )

Let’s break down the jq filters:

1. .

Print unchanged output. Takes in the whole string and transforms it into JSON. Useful when taking a string of characters from stdout and converting into a JSON object.

Result:

 // Unchanged JSON object
 {
   "tailwindcss": {
     "current": "2.0.2",
     "wanted": "2.0.2",
     "latest": "2.0.3",
   },
   "typescript": {
     "current": "4.1.3",
     "wanted": "4.1.3",
     "latest": "4.2.2",
      // ...
   }
 }

2. keys

Returns an array of all the object keys. Similar to JavaScript Object.keys() function.

Result:

 [
    'tailwindcss',
    'typescript'
 ]

3. map(.+"@latest")

Loop over all items. Appends “@latest” to each item. Map is similar to the JavaScript Array built-in method map(). It takes a function that is applied to each item. The dot . operator means current item and + is the string concatenator. Similar to JavaScript, the + addition function takes the data types into consideration when performing an “addition”.

Result:

 [
    'tailwindcss@latest',
    'typescript@latest'
 ]

4. join(" ")

Join all array items into one string joined by a string, in this case a space. Again this is very similar to the JavaScript Array join() method. Notice it prints the string with double quotes.

Result:

 "tailwindcss@latest typescript@latest"

5. --raw-output

Print without formatting as a JSON string.

Once the inner command is expanded it looks like:

 npm install tailwindcss@latest typescript@latest

Conclusion

This is just a brief introduction to how jq can be integrated into any workflow. It is a very powerful tool that can greatly improve your productivity. For example, I also use jq to manage responses from the Cloudflare API and redirect those responses to other commands. Once you become aware of what it can do it becomes easier to see applications for it.

I am available for hire.

Loading Comments