Get version number from package.json in React Redux (create-react-app)

81,270

Solution 1

From your edit I would suggest to try:

import packageJson from '/package.json';

You could also try to create a symlink:

# From the project root.
cd src; ln -s ../package.json package.alias.json

List contents of src directory and you'll see the symlink.

ls
#=> package.alias.json -> ../package.json

Adding the .alias helps reduce the "magic" for others and your future self when looking at this. Plus, it'll help text editors keep them apart. You'll thank me later. Just make sure you update your JS code to import from ./package.alias.json instead of ./package.json.

Also, please take a look at this question: The create-react-app imports restriction outside of src directory

Solution 2

Solving this without importing and exposing package.json to the create-react-app

Requires: version 1.1.0+ of create-react-app

.env

REACT_APP_VERSION=$npm_package_version
REACT_APP_NAME=$npm_package_name

index.js

console.log(`${process.env.REACT_APP_NAME} ${process.env.REACT_APP_VERSION}`)

Note: the version (and many other npm config params) can be accessed

Note 2: changes to the .env file will be picked only after you restart the development server

Solution 3

Try this.

// in package.json
"version": "1.0.0"

// in index.js
import packageJson from '../package.json';
console.log(packageJson.version); // "1.0.0"

Solution 4

I don't think getting version by 'import' or 'require' package is correct. You can add a script in you package.json

"start": "REACT_APP_VERSION=$npm_package_version react-app-script start",

You can get it by "process.env.REACT_APP_VERSION" in any js files.

It also works in build scripts, like this:

"build": "REACT_APP_VERSION=$npm_package_version react-app-script build",

Solution 5

import package.json

Generally speaking, importing package.json is not good. Reasons: security & bundle size concerns

Yes, latest webpack (default config) + ES6 import does tree-shaking (i.e. only includes the "version" value instead of the whole package.json) for both import packageJson from '../package.json' and import { version } from '../package.json'. But it is not guaranteed if you use CommonJS (require()), or have altered your webpack config, or use another bundler/transpiler. It's weird to rely on bundler's tree-shaking to hide your sensitive data. If you insist on importing package.json but do not want the whole package.json exposed, you may want to add some post-build checks to ensure other values in package.json are removed.

However the security concern here remains theoretical for open source projects whose package.json is public after all. If both security and bundle size are not problems, or, the non-guaranteed tree-shaking is good enough for you, then go ahead)

.env

The .env method, if it works, then it's good, but if you don't use create-react-app, you might need to install dotenv and do some additional configurations. There's also one small concern: it is not recommended to commit the .env file (here and here), but if you do the .env method, it looks like you will have to commit the file as it likely becomes essential for your program to work.

Best practice (arguably)

(this is not primarily for create-react-app, but you still can either use react-app-rewired or eject cra in order to configure webpack in cra)

If you use webpack, then with DefinePlugin:

plugins: [
  new webpack.DefinePlugin({
    'process.env.VERSION': JSON.stringify(
      process.env.npm_package_version,
    ),
  }),
]

You can now use console.log(process.env.VERSION) in your front-end program (development or production).

(You could simply use VERSION instead of process.env.VERSION, but it usually requires additional configuration to satisfy linters: add globals: {VERSION: 'readonly'} in .eslintrc (doc); add declare var VERSION: string; in .d.ts file for TypeScript)

Although it's "npm_package_version", it works with yarn too. Here's a list of npm's exposed environment variables.

Other bundlers may have similar plugins, for example, @rollup/plugin-replace.

Share:
81,270
Baldeep
Author by

Baldeep

Updated on January 15, 2022

Comments

  • Baldeep
    Baldeep over 2 years

    OP EDIT: If anyone else comes across this: the app was created using create-react-app, which limits importing to within the src folder. However if you upgrade react-scripts to v1.0.11 it does let you access package.json.

    I'm trying to get the version number from package.json in my app.

    I've already tried these suggestions, but none of them have worked as I can't access package.json from outside the src folder (might be due to React, I'm new to this). Moving package.json into src then means I can't run npm install, npm version minor, and npm run build from my root folder. I've tried using process.env.npm_package_version but that results in undefined.

    I'm using Jenkins, and I haven't set it up to push the commits up yet, but the only idea I have is to get the version from the tags in GitLab, but I have no idea how to do that, and it would add unnecessary dependency to the repo, so I would really like to find an alternative.

    EDIT: My file structure is like:

    --> RootAppFolder
        |--> build
        |--> node_modules
        |--> public
        |--> src
             |--> Components
                  |--> Root.js
        |
        |--> package.json
    

    So to access package.json from Root.js I have to do import packageJson from './../../package.json' and then I get the following error:

    ./src/components/Root.js

    Module not found: You attempted to import ./../../package.json which falls outside of the project src/ directory. Relative imports outside of src/ are not supported. You can either move it inside src/, or add a symlink to it from project's node_modules/.

  • Baldeep
    Baldeep over 6 years
    While the imports still didn't work, I didn't realise the app was created using create-react-app which is where the issue is coming from. So I guess the solution then, is to look into webpack and configure it myself and get rid of this limitation.
  • MC10
    MC10 over 6 years
    Using Expo and this worked like a charm for me. I called mine appJson, so it was console.log(appJson.expo.version);. Thanks!
  • Joshua Pinter
    Joshua Pinter about 6 years
    As the OP mentioned in an edit to their question, this is no longer necessary. Newer versions of react-scripts allows you to import from outside of src.
  • Breaker222
    Breaker222 over 5 years
    I had to create .env (as plain text file) in repository root to make it work. like it
  • acidernt
    acidernt over 5 years
    This will import whole package.json in your bundle
  • Stephen Saucier
    Stephen Saucier almost 5 years
    @inferus-vv you can import { version } from '../package.json';
  • Joe Maffei
    Joe Maffei almost 5 years
    Adding package.json to your bundle is not a good idea. It would expose all your dependencies to potential attackers, plus it's a fairly large object and the data you need is only a handful of bytes.
  • Chunky Chunk
    Chunky Chunk over 4 years
    @JoeMaffei This is a fine solution, but referencing the package.json file with import { name, version } from "../package.json"; is less cryptic and doesn't require creating an .env file.
  • Alina_Lapina
    Alina_Lapina over 4 years
    insecure! you don't want to expose your package.json to users and hackers
  • Onkeltem
    Onkeltem about 4 years
    @TheDarkIn1978 But it's not gonna work with Create React App as it doesn't allow to reference outside of src/.
  • ZYinMD
    ZYinMD almost 4 years
    Don't forget to npm start again after changing .env
  • Teodor Ciuraru
    Teodor Ciuraru over 3 years
    @Alina_Lapina does this apply when talking about RN packages as well? Already when publishing my package I expose the package.json (and any other packages do this as well)
  • Teodor Ciuraru
    Teodor Ciuraru over 3 years
    @EricBurel does this apply when referring to RN packages as well? I already expose the package.json when publishing my package (and any other packages do this as well).
  • Eric Burel
    Eric Burel over 3 years
    Probably yes, if you bundle it into the app then the user can access it. This isn't the craziest leak but still a leak
  • Alina_Lapina
    Alina_Lapina over 3 years
    @TeodorCiuraru, yes it does. Take a look create-react-app.dev/docs/adding-custom-environment-variable‌​s/… React lib has a mechanism for this. Define REACT_APP_<SOMETHING> environment variables to expose selected setup data, but not the setup itself.
  • jefelewis
    jefelewis over 3 years
    import packageJson from '/package.json'; worked for me. For Typescript users, add "resolveJsonModule": true,
  • stephent
    stephent over 3 years
    Just found that NEXT_PUBLIC_APP_VERSION=$npm_package_version in an .env file works for next.js (I'm using 9.5.3) also, although I don't see it documented anywhere.
  • Saber Hayati
    Saber Hayati over 3 years
    You must create custom environment variables beginning with REACT_APP_. Any other variables except NODE_ENV will be ignored
  • Nikita Malyschkin
    Nikita Malyschkin about 3 years
    That's a verbose and very helpful answer, thank you! :) Let's say I have bundled my package.json with my application, what would be the security concerns?
  • Tom Chen
    Tom Chen about 3 years
    @NikitaMalyschkin if you have already included the whole package.json in your production code, then there would be no additional concern when you import it for the version number. But you might want to revise the decision to include the whole package.json in the first place.
  • Andrew Koster
    Andrew Koster about 3 years
    What is this "sensitive information" that everyone is including in their package.json? Every package.json that I've ever seen is just a boring list of dependencies and version numbers. Who cares if someone sees it by decompiling the app? I don't see the security concern with just importing package.json. No one has explained what this supposed security concern is, everyone is just stating that it exists.
  • Andrew Koster
    Andrew Koster about 3 years
    Who cares if someone decompiles the app and sees that it uses whatever library? Why is this a security concern? The only way to prevent people from decompiling your code is not to ship a binary in the first place.
  • Andrew Koster
    Andrew Koster about 3 years
    How is package.json a "fairly large object", too large to import? It's a few lines of JSON.
  • Tom Chen
    Tom Chen about 3 years
    @AndrewKoster if it's an open source project, then there's no such concern. If it's private, then dependency list and other configurations may reveal things the project's owner does not want to be publicly known. For example if a vulnerability of a dependency is found, it's easier for hackers to launch some so-called 0-day attacks.
  • Tom Chen
    Tom Chen about 3 years
    @AndrewKoster It's also possible for hackers to find a way to change a known upstream dependency in order to attack the downstream dependencies and apps. E.g. you know a big big website is using library A, you "social engineer" library A's maintainer and get access and add a bitcoin miner in the code, then all the big big website's viewers will mine Bitcoin for you... It may not be exactly like what I said but it actually happened before, you can Google it
  • Tom Chen
    Tom Chen about 3 years
    @AndrewKoster It's not that front-end does not need to worry about security, there are SQL injection and cross-site-related stuff to worry about. It's true that if your front and back are well separated and backend API endpoints are well writen, fewer security problems front-end will need to handle, but such problems do exist. Futhermore, package.json may sometimes reveal backend dependencies and config if a (incompetent) dev uses node in backend and uses a same package.json or at least put some back dependencies & configs in the package.json...
  • M1sterPl0w
    M1sterPl0w almost 3 years
    This solution doens't work when you make of prod build of your react app. In my case (not a really experienced react developer, so correct me if I am wrong) I didn't have a package.json in my build folder, after building.
  • Yoofi Brown-Pobee
    Yoofi Brown-Pobee over 2 years
    How would this work for JSON env files like env-cmdrc? It has trouble parsing
  • Joshua Pinter
    Joshua Pinter over 2 years
    What about just importing the version like import { version } from '../package.json';. Does that avoid the security risk and bundle size concerns?