53

For example:

  • I have version 2.0.0 of package-name installed.
  • The latest minor version that has the same major version is 2.1.2
  • The latest major version (which would be installed if I ran npm install package-name@latest is 4.3.0

How can I install the most recent package that does not have breaking changes?

mikemaccana
  • 110,530
  • 99
  • 389
  • 494

7 Answers7

67

Use npm install package-name@"<next-major.0.0"

For example:

npm install package-name@"<3.0.0" would install the latest right before 3.0.0 (e.g. 2.11.1)

Kevin Danikowski
  • 4,620
  • 6
  • 41
  • 75
  • 6
    I wish there were something like `npm install package-name@latest-non-breaking` (or yarn to do this), but 'latest right before 3.0.0' is still the best answer I've had so far. Thanks! – mikemaccana May 24 '18 at 19:09
22

Npm uses semver, so you can use a variety of thing for getting close to your goal

Looking at the offical documentation, you could use something like:

npm install package-name@">=2.1.2 <2.2.0"

further more there are a lot of variety of ranges so you can use this forms Advanced Range Syntax as you can see, this is a sample an interesting extract from the semver repo at the end is the answer for you:

Advanced range syntax desugars to primitive comparators in deterministic ways.

Advanced ranges may be combined in the same way as primitive comparators using white space or ||. Hyphen Ranges X.Y.Z - A.B.C

Specifies an inclusive set.

1.2.3 - 2.3.4 := >=1.2.3 <=2.3.4

If a partial version is provided as the first version in the inclusive range, then the missing pieces are replaced with zeroes.

1.2 - 2.3.4 := >=1.2.0 <=2.3.4

If a partial version is provided as the second version in the inclusive range, then all versions that start with the supplied parts of the tuple are accepted, but nothing that would be greater than the provided tuple parts.

1.2.3 - 2.3 := >=1.2.3 <2.4.0
1.2.3 - 2 := >=1.2.3 <3.0.0

X-Ranges 1.2.x 1.X 1.2.* *

Any of X, x, or * may be used to "stand in" for one of the numeric values in the [major, minor, patch] tuple.

* := >=0.0.0 (Any version satisfies)
1.x := >=1.0.0 <2.0.0 (Matching major version)
1.2.x := >=1.2.0 <1.3.0 (Matching major and minor versions)

A partial version range is treated as an X-Range, so the special character is in fact optional.

"" (empty string) := * := >=0.0.0
1 := 1.x.x := >=1.0.0 <2.0.0
1.2 := 1.2.x := >=1.2.0 <1.3.0

Tilde Ranges ~1.2.3 ~1.2 ~1

Allows patch-level changes if a minor version is specified on the comparator. Allows minor-level changes if not.

~1.2.3 := >=1.2.3 <1.(2+1).0 := >=1.2.3 <1.3.0
~1.2 := >=1.2.0 <1.(2+1).0 := >=1.2.0 <1.3.0 (Same as 1.2.x)
~1 := >=1.0.0 <(1+1).0.0 := >=1.0.0 <2.0.0 (Same as 1.x)
~0.2.3 := >=0.2.3 <0.(2+1).0 := >=0.2.3 <0.3.0
~0.2 := >=0.2.0 <0.(2+1).0 := >=0.2.0 <0.3.0 (Same as 0.2.x)
~0 := >=0.0.0 <(0+1).0.0 := >=0.0.0 <1.0.0 (Same as 0.x)
~1.2.3-beta.2 := >=1.2.3-beta.2 <1.3.0 Note that prereleases in the 1.2.3 version will be allowed, if they are greater than or equal

to beta.2. So, 1.2.3-beta.4 would be allowed, but 1.2.4-beta.2 would not, because it is a prerelease of a different [major, minor, patch] tuple.

Caret Ranges ^1.2.3 ^0.2.5 ^0.0.4

Allows changes that do not modify the left-most non-zero digit in the [major, minor, patch] tuple. In other words, this allows patch and minor updates for versions 1.0.0 and above, patch updates for versions 0.X >=0.1.0, and no updates for versions 0.0.X.

Many authors treat a 0.x version as if the x were the major "breaking-change" indicator.

Caret ranges are ideal when an author may make breaking changes between 0.2.4 and 0.3.0 releases, which is a common practice. However, it presumes that there will not be breaking changes between 0.2.4 and 0.2.5. It allows for changes that are presumed to be additive (but non-breaking), according to commonly observed practices.

^1.2.3 := >=1.2.3 <2.0.0
^0.2.3 := >=0.2.3 <0.3.0
^0.0.3 := >=0.0.3 <0.0.4
^1.2.3-beta.2 := >=1.2.3-beta.2 <2.0.0 Note that prereleases in the 1.2.3 version will be allowed, if they are greater than or equal

to beta.2. So, 1.2.3-beta.4 would be allowed, but 1.2.4-beta.2 would not, because it is a prerelease of a different [major, minor, patch] tuple. ^0.0.3-beta := >=0.0.3-beta <0.0.4 Note that prereleases in the 0.0.3 version only will be allowed, if they are greater than or equal to beta. So, 0.0.3-pr.2 would be allowed.

When parsing caret ranges, a missing patch value desugars to the number 0, but will allow flexibility within that value, even if the major and minor versions are both 0.

^1.2.x := >=1.2.0 <2.0.0
^0.0.x := >=0.0.0 <0.1.0
^0.0 := >=0.0.0 <0.1.0

A missing minor and patch values will desugar to zero, but also allow flexibility within those values, even if the major version is zero.

^1.x := >=1.0.0 <2.0.0
^0.x := >=0.0.0 <1.0.0

so summarizing your example could be

npm install package-name@"^2.1.x"
anquegi
  • 11,125
  • 4
  • 51
  • 67
8

you can use following two methods:-

In the simplest terms, the tilde matches the most recent minor version (the middle number). ~1.2.3 will match all 1.2.x versions but will miss 1.3.0.

The caret, on the other hand, is more relaxed. It will update you to the most recent major version (the first number). ^1.2.3 will match any 1.x.x release including 1.3.0, but will hold off on 2.0.0.

http://fredkschott.com/post/2014/02/npm-no-longer-defaults-to-tildes/

Vivek Sharma
  • 164
  • 1
  • 8
  • 4
    "The caret will update you to the most recent major version (the first number). " conflicts with "^1.2.3 will ...hold off on 2.0.0." - will it hold off on 2.0.0, the major version, or not? – mikemaccana Sep 16 '16 at 13:58
  • as i said if you want the version as 2.x.x which is minor one you can do like this ^2.1.2 which is known latest minor version. it won't download the 3.x.x or 4.x.x. – Vivek Sharma Sep 16 '16 at 14:03
  • 5
    I understand that, but those sentences still conflict. – mikemaccana Sep 16 '16 at 16:52
  • Did you tried it? and can you share the package name so that i can try this and give you proper solution. – Vivek Sharma Sep 16 '16 at 16:58
  • 5
    Agree with @mikemaccana - your sentences are contradictory. And from the other answer, it's actually more complicated than that. – Simon East May 05 '17 at 00:16
7

major.minor.patch = 1.0.3

major version = 1 , minor version = 0 , patch version = 3

  • Major, minor and patch represent the different releases of a package.
  • tilde (~) and caret (^) to designate which patch and minor versions to use respectively.
  • ~1.0.3 - means to install version 1.0.3 or the latest patch version such as 1.0.6.
  • ^1.0.3 - means to install version 1.0.3 or the latest minor or patch version such as 1.4.0.
  • if npm package.json referencing a package that hasn’t reached version 1.0 yet, using the caret(^) symbol will only grab the patch version.
Ritu Gupta
  • 2,249
  • 1
  • 18
  • 11
2

It seems like npm can't do this out of the box, but it can be done with npm-check-updates:

  1. Run ncu to update package.json

    npx --package npm-check-updates ncu --target minor -u
    
  2. Update package-lock.json

    npm install
    

Here's a sample before/after:

$ npm outdated
Package                             Current  Wanted  Latest  Location
@typescript-eslint/eslint-plugin     5.36.2  5.36.2  5.57.0  node_modules/@typescript-eslint/eslint-plugin
@typescript-eslint/parser            5.36.2  5.36.2  5.57.0  node_modules/@typescript-eslint/parser
eslint                               8.23.1  8.23.1  8.37.0  node_modules/eslint
eslint-config-prettier                8.5.0   8.5.0   8.8.0  node_modules/eslint-config-prettier
eslint-plugin-typescript-sort-keys    2.1.0   2.1.0   2.3.0  node_modules/eslint-plugin-typescript-sort-keys
husky                                 8.0.1   8.0.1   8.0.3  node_modules/husky
lint-staged                          13.0.3  13.0.3  13.2.0  node_modules/lint-staged
prettier                              2.7.1   2.7.1   2.8.7  node_modules/prettier
typescript                            4.8.3   4.8.3   5.0.2  node_modules/typescript

$ npx --package npm-check-updates ncu
...

$ npm outdated
Package                             Current  Wanted  Latest  Location
@typescript-eslint/eslint-plugin     5.36.2  5.57.0  5.57.0  node_modules/@typescript-eslint/eslint-plugin
@typescript-eslint/parser            5.36.2  5.57.0  5.57.0  node_modules/@typescript-eslint/parser
eslint                               8.23.1  8.37.0  8.37.0  node_modules/eslint
eslint-config-prettier                8.5.0   8.8.0   8.8.0  node_modules/eslint-config-prettier
eslint-plugin-typescript-sort-keys    2.1.0   2.3.0   2.3.0  node_modules/eslint-plugin-typescript-sort-keys
husky                                 8.0.1   8.0.3   8.0.3  node_modules/husky
lint-staged                          13.0.3  13.2.0  13.2.0  node_modules/lint-staged
prettier                              2.7.1   2.8.7   2.8.7  node_modules/prettier
typescript                            4.8.3   4.9.5   5.0.2  node_modules/typescript

$ npm install
...

$ npm outdated
Package     Current  Wanted  Latest  Location
typescript    4.9.5   4.9.5   5.0.2  node_modules/typescript
...


bmaupin
  • 14,427
  • 5
  • 89
  • 94
2

You can use caret ^, tilde ~ or placeholders x.

That's the same stuff you'll find autogenerated in your package.json file.

In SemVer (semantic versioning), the segments are major.minor.patch.

  • ^ will match the latest minor version.
  • ~ will match the latest patch version.
  • x will match the latest on the position, where it is used.
  • @latest or nothing will match the latest.

Take yarn package as an example. There is a reason why people would choose v1 instead of v2.

All these will install 1.22.19 (which is current v1 latest).

npm i yarn@1.x
npm i yarn@1.x.x
npm i yarn@^1
# edge cases
npm i yarn@~1    # install latest patch, if minor is not specified use latest
npm i yarn@^1.2  # caret matches latest minor. Specified minor x.2 is ignored.

All these will install 1.15.2.

npm i yarn@1.15.x
npm i yarn@~1.15
# edge cases
npm i yarn@~1.15.1  # tilde matches latest patch. Specified patch x.x.1 is ignored.

note, when installing with yarn on Windows

A caret (^) character in a command line means that the character immediately following it is interpreted literally, rather than as a control character. sauce

It is therefore necessary to quote the package version

yarn add "yarn@^1"

The best way to learn is with a hands on trial and error with a SemVer Calculator.
https://semver.npmjs.com/

enter image description here

Qwerty
  • 29,062
  • 22
  • 108
  • 136
0

I had the same issue, and, coming from a Java & Maven environment, I would first search the https://www.npmjs.com/ for each of my specific package.

Then I would look at the Versions tab of the package and find out more about its versions. I assume that major versions bring breaking changes, while minor versions contain only code improvements and bug fixes, at least this is the convention. But reading the manual always helps :)

Sometimes, the version predicates can be composed like this: "codelyzer@5.2.2 requires a peer of @angular/compiler@>=2.3.1 <10.0.0 || >9.0.0-beta <10.0.0 || >9.1.0-beta <10.0.0 || >9.2.0-beta <10.0.0 but none is installed. You must install peer dependencies yourself."

razvanone
  • 1,351
  • 18
  • 27