Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Extract version from package.json (NPM) using bash / shell
# Version key/value should be on his own line
PACKAGE_VERSION=$(cat package.json \
| grep version \
| head -1 \
| awk -F: '{ print $2 }' \
| sed 's/[",]//g')
echo $PACKAGE_VERSION
@amio
Copy link

amio commented Mar 28, 2020

Just added this to nls cli (since 3.1.0):

$ nls v

@jdvivar
Copy link

jdvivar commented Apr 8, 2020

If someone wants to get the version of every lerna package, following previous comments (thank you!), it's:

$ npx lerna exec -- "node -pe \"require('./package.json').version\""

@mightyiam
Copy link

mightyiam commented Apr 23, 2020

$ npm show . version seems to do the trick.

@amio
Copy link

amio commented Apr 23, 2020

@mightyiam No, it actually look up npm registry for published version:

/tmp $ mkdir test                                                                                                                   22:45:10
 
/tmp $ cd test                                                                                                                      22:45:12
 
/t/test $ npm init -y                                                                                                               22:45:14
Wrote to /private/tmp/test/package.json:

{
  "name": "test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}


 
/t/test $ npm show . version                                                                                                        22:45:17
0.6.0
 
/t/test $ npm v test                                                                                                                22:45:35

test@0.6.0 | Proprietary | deps: 1 | versions: 23

@damlys
Copy link

damlys commented Apr 26, 2020

it's an improvement to @jakwuh solution: https://gist.github.com/DarrenN/8c6a5b969481725a4413#gistcomment-1971123


node --eval="process.stdout.write(require('./package.json').version)" doesn't add any trailing symbols to the output. Full example:

$ pwd
/home/damlys/workspace/get-npm-package-version
$ ls
package.json
$ cat package.json
{
  "name": "myapp",
  "version": "0.1.0-rc.1+5398d0bde599de3ed5fc87e41af208e4754cbd52",
  "private": true
}
$ node --eval="process.stdout.write(require('./package.json').version)"
0.1.0-rc.1+5398d0bde599de3ed5fc87e41af208e4754cbd52$ export PACKAGE_VERSION=$(node --eval="process.stdout.write(require('./package.json').version)")
$ echo $PACKAGE_VERSION
0.1.0-rc.1+5398d0bde599de3ed5fc87e41af208e4754cbd52
$ echo "v${PACKAGE_VERSION}_FOO_BAR_BAZ"
v0.1.0-rc.1+5398d0bde599de3ed5fc87e41af208e4754cbd52_FOO_BAR_BAZ
$

@dezren39
Copy link

dezren39 commented Jul 5, 2020

I combined all the examples mostly here but also elsewhere into one big page, no idea what is best, but if it's useful to someone:

https://gist.github.com/dezren39/d71e381a3c70ce8463a9471cd2983617

# these can all be npm scripts, but anything can be an npm script

# a
echo $(cat ./package.json | grep version | head -1 | awk -F: '{ print $2 }' | sed 's/[",]//g' | tr -d '[[:space:]]')
# b
echo $(cat ./package.json | grep version | head -1 | awk -F= "{ print $2 }" | sed -E 's/(version)|[:,\",]//g' | tr -d '[[:space:]]')

# c
echo $(node --eval="process.stdout.write(require('./package.json').version)")

# d
node -pe "require('./package.json').version"

# e
jq -r .version ./package.json

# f
npm run version --silent # add version run-script to scripts: ' "version": "echo $npm_package_version" ' # also could access $npm_package_version any other way

# g not clean
npm version

# if published package, to check published package
# h
npm view . version
# i
npm show . version

# j
awk -F\" '/"version":/ {print $4}' package.json
# k
npx -c 'echo "$npm_package_version"'
# l
perl -ne 'print "$1\n" if /"version":\s*"(.*?)"/' package.json
# m
awk '/version/{gsub(/("|",)/,"",$2);print $2}' package.json
# n
sed -nr 's/^\s*\"version": "([0-9]{1,}\.[0-9]{1,}.*)",$/\1/p' package.json

#---

# npm package example, others exist

npm i -g json

# o (requires "npm i -g json")
json version -a < package.json

# p (requires "npm i -g json")
json dependencies -a < package.json | grep : | sed 's/^ *//;s/"//g;s/: /@/;s/,$//'
# q (requires "npm i -g json")
json dependencies -a < package.json | grep : | sed 's/[",]//g;s/: /@/;s/,$//'

# r (requires "npm i -g json")
json devDependencies -a < package.json | grep : | sed 's/^ *//;s/"//g;s/: /@/;s/,$//'

# s (requires "npm i -g json")
json devDependencies -a < package.json | grep : | sed 's/[",]//g;s/: /@/;s/,$//'

#---

# t
# https://gist.github.com/DarrenN/8c6a5b969481725a4413#gistcomment-3416434
grep version package.json | awk -F \" '{print $4}'

@tribal2
Copy link

tribal2 commented Aug 13, 2020

grep version package.json | awk -F \" '{print $4}'

@maitrungduc1410
Copy link

maitrungduc1410 commented Nov 21, 2020

Simple solution for both Mac and Linux: (works great even if there's multiple keywords version in your package.json)

awk -F'"' '/"version": ".+"/{ print $4; exit; }' package.json

@katlimruiz
Copy link

katlimruiz commented Dec 11, 2020

To remove spaces I simply added the space to the sed expression, and removed the new lines

PACKAGE_VERSION=$(cat package.json|grep version|head -1|awk -F: '{ print $2 }'|sed 's/[", ]//g')

@ild0tt0re
Copy link

ild0tt0re commented Jan 17, 2021

Simple solution for both Mac and Linux: (works great even if there's multiple keywords version in your package.json)

awk -F'"' '/"version": ".+"/{ print $4; exit; }' package.json

Thanks! @maitrungduc1410, the faster and simpler solution!
Verified with time:

$ time awk -F \" '/"version": ".+"/ { print $4; exit; }' package.json

@roalcantara
Copy link

roalcantara commented Jun 8, 2021

To remove spaces I simply added the space to the sed expression, and removed the new lines

PACKAGE_VERSION=$(cat package.json|grep version|head -1|awk -F: '{ print $2 }'|sed 's/[", ]//g')

Given a package.json containing

{
  "private": true,
  "version": "0.1.0",
  "license": "MIT",
  "scripts": {
    "version": "echo $npm_package_version"
  }
}

And the version attribute consists only of digits and periods
When executing - on both mac or alpine Linux - I've got

$ cat ./package.json | grep -m 1 version | sed 's/[^0-9.]//g'
0.1.0

Is there a way to get rid of either sed or grep? ๐Ÿค”

@smendoza787
Copy link

smendoza787 commented Jun 25, 2021

Incredible, thank you.

@aasmpro
Copy link

aasmpro commented Jul 11, 2021

used
grep '"version"' package.json | cut -d '"' -f 4 | head -n 1
and for anyone who seeks to use it in .gitlab-ci.yml, check the before_script section bellow:

build:dev:
  stage: build:dev
  variables:
    NAMESPACE: "dev"
  before_script:
    - PROJECT_VERSION=$(grep '"version"' package.json | cut -d '"' -f 4 | head -n 1)
  script:
    - docker build --network host -f ./Dockerfile -t $CI_REGISTRY_IMAGE:$NAMESPACE-$PROJECT_VERSION-$CI_PIPELINE_ID .
  only:
    - develop
  tags:
    - build_sv

@alvis
Copy link

alvis commented Aug 17, 2021

Since npm 7.20, we have a simpler solution

npm pkg get version

The output is in JSON format with a double quote.
To remove it, use this

npm pkg get version | sed 's/"//g'

@roalcantara
Copy link

roalcantara commented Aug 17, 2021

Awesome, @alvis! ๐Ÿ˜

This is my new favourite! ๐Ÿ‘๐Ÿผ๐Ÿ‘๐Ÿผ๐Ÿ‘๐Ÿผ๐Ÿ‘๐Ÿผ๐Ÿ‘๐Ÿผ๐Ÿ‘๐Ÿผ

Since npm 7.20, we have a simpler solution

npm pkg get version

The output is in JSON format with a double quote.
To remove it, use this

npm pkg get version | sed 's/"//g'

When it comes to performance, do u happen to know if is it the same (or better) than

npm pkg get version | tr -d '"'`

? ๐Ÿค”

@fatso83
Copy link

fatso83 commented Aug 25, 2021

@roalcantara You are asking if two commands that replace two bytes in a short string have different performance. This is talk of microseconds at best. If you really wonder about something, do a test. Here is the performance of the sole NPM command:

$ time command npm pkg get version
"0.0.1"

real	0m0.218s
user	0m0.156s
sys	0m0.050s

carlerik at carl-eriks-air in ~/dev/nimble/frontend (2978-vite-build)
$ time npm pkg get version
"0.0.1"

real	0m0.262s
user	0m0.154s
sys	0m0.055s

I ran it twice, as caching in the file system affects the result. The important bit is that the "user" and "sys" time is consistent: about 150ms of cpu time. That is JUST for invoking NPM.

Now, just see how the two other commands we pipe this into fares:

$ time (echo "0.0.1" |  sed 's/"//g') > /dev/null && time (echo "0.0.1" |   tr -d '"') > /dev/null

real	0m0.030s
user	0m0.001s
sys	0m0.009s

real	0m0.004s
user	0m0.001s
sys	0m0.003s

As you see, none of these commands take more than a single millisecond of cpu time.

@tsulli
Copy link

tsulli commented Oct 14, 2021

I like @GuyMograbi approach = THANKS!

In package.json:

"version": "0.0.1"
"scripts": {
     "version": "echo $npm_package_version"
}

In a terminal:

npm run version

I don't see it mentioned anywhere in this thread, but in case it helps the Windows version of "echo $npm_package_version" is "echo %npm_package_version%".

@fatso83
Copy link

fatso83 commented Oct 14, 2021

@tsulli Instead of making scripts that are OS dependant you can just use the fact that any version of NPM >= 7.20 can do this without any hackery: npm pkg get will get any part of the structure you want, from root and down. No args, meaning the whole tree. npm pkg get version will get you the version.

@bmerigan
Copy link

bmerigan commented Nov 17, 2021

No need for sed or grep here. I solved the issue in a deploy script with

awk '/version/{gsub(/("|",)/,"",$2);print $2};' package.json

This actually captures EVERY version number in the file.

@ThePlenkov
Copy link

ThePlenkov commented Nov 23, 2021

npx -c 'echo "$npm_package_version"' unfortunately doesn't work in Windows.
I only could use npx -c 'node -p "process.env.npm_package_version"'
or

npm run get:version --silent

where "get:version": "node -p \"process.env.npm_package_version\""

npm run works a bit faster than npx.

Also I do not support to call script version, because it will trigger also preversion and postversion scripts which many projects have

@appurist
Copy link

appurist commented Apr 25, 2022

@fatso83 That npm pkg get version command is unreliable, strangely dependent on whatever the current folder name is.

I have a folder named desk-app the same as the name field in my package.json and it reports:

{
  "desk-app": "1.0.4220"
}

Now if I rename the current folder to desk-app2 and run the same command (npm pkg get version), I get:
"1.0.4220"
which is what I want here.
Not only does the first version introduce uncertainty in the process, but it actually changes the name of the field to the name of the app, instead of "version". This makes it usable to me. I'm still looking for a cross-platform that also works on windows.

@appurist
Copy link

appurist commented Apr 25, 2022

For anyone else looking for a cross-platform solution (not reliant on Unix shell commands like grep/awk/sed) and local (without external dependencies), since it can be assumed that Node.js is installed, and it's already cross-platform for this, I just created a make_version.js file with:

const PACKAGE_VERSION = require("./package.json").version;
console.log(`export const PACKAGE_VERSION = "${PACKAGE_VERSION}";`);
console.error("package.json version:", PACKAGE_VERSION);

and added a version command to package.json:

scripts: {
    "version": "node make_version.js > src/version.js",

and then added:

    "prebuild": "npm run version",
    "prestart": "npm run version",

and it creates a new src/versions.js on every start or build. Of course this can be easily tuned in the version script to be a different location, or in the make_version.js file to output different syntax and constant name, etc.

@acrogenesis
Copy link

acrogenesis commented May 5, 2022

cat package.json | jq -r '.version' works on github actions

@iamludal
Copy link

iamludal commented May 13, 2022

cat package.json | jq -r '.version' works on github actions

This is the best solution!

@bmerigan
Copy link

bmerigan commented May 13, 2022

cat package.json | jq -r '.version' works on github actions

This is the best solution!

Not the best IMO because you need to install additional software for it to work (jq)

@appurist
Copy link

appurist commented May 13, 2022

I'm with @bmerigan, jq is not cross-platform or installed by default (and not available on Windows). This is why I ended up using that 3-line Node.js script, because it can be assumed that Node.js is installed here, and is cross-platform.

@iamludal
Copy link

iamludal commented May 14, 2022

Well you're right, I should have been more precise: this is the best solution for my use case, because I'm using it in GitHub Actions, and jq is installed by default.

@mr-kelly
Copy link

mr-kelly commented May 15, 2022

awk -F'"' '/"version": ".+"/{ print $4; exit; }' package.json

This solution is greatest and can be suited for a special situation:

My package.json has more than one key element with "version" string.

@cmario92
Copy link

cmario92 commented Jul 5, 2022

any example that we can wrap any of the above solutions in a sh command?
The goal for me is to extract the package.json version in a jenkinsfile.

@appurist
Copy link

appurist commented Jul 5, 2022

@cmario92 my simple solution only had a dependency on Node.

It's easy to change the output node make_version.js > src/version.js to be a different language or json file or append to a jenkinsfile etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment