55

I'm trying to import my package.json file in TypeScript and it doesn't seem to work. Specifically, I'm just trying to import it so that I can access the name and version properties for a log statement. Something like:

import * as pjson from '../package.json';
// other code here
log.info(`${pjson.name}:${pjson.version}` started on port ...);

We have this same syntax elsewhere in other projects that use Node/Babel, but I'm trying to introduce some TypeScript around these parts. Elsewhere we'd do something like:

import { name, version} from '../package.json';

That doesn't work here however. I followed the instructions at https://www.npmjs.com/package/json-d-ts which at least made the error on my import statement go away, but now when I try to access properties I get the following error:

src/index.ts(20,21): error TS2339: Property 'name' does not exist on type 'typeof import("*.json")'.
src/index.ts(20,35): error TS2339: Property 'version' does not exist on type 'typeof import("*.json")'.

Is there a way to fix this, or do I just have to hardcode these values somewhere (rather than dynamically retrieving them from package.json)? Maybe I can declare a type for import("*.json") somehow with these properties defined on it?

0

6 Answers 6

78

How to import *.json ?

As already answered you need Typescript >= 2.9 and the following settings in tsconfig.json:

{
  "resolveJsonModule": true,
  "esModuleInterop": true,
  "module": "commonjs"
}

But there are restrictions:

  • You must compile to CommonJS
  • All your imported JSONs must reside under the "rootDir"

Unfortunately the "rootDir" is very often a folder beneath package.json like './src' and things would fail.

So:
How to import package.json ? You can require it:
const pjson = require('../package.json');

If you use npm.start: you don't need to :

The package.json fields are tacked onto the npm_package_ prefix. So, for instance, if you had {"name":"foo", "version":"1.2.5"} in your package.json file, then your package scripts would have the npm_package_name environment variable set to “foo”, and the npm_package_version set to “1.2.5”. You can access these variables in your code with process.env.npm_package_name and process.env.npm_package_version, and so on for other fields.

Sign up to request clarification or add additional context in comments.

4 Comments

Upvote for including issue with package.json being outside the rootDir.
Note that the environment variables also work for those of us using yarn (the field names are still prefixed with "npm_package_").
"process.env.npm_package_version" - was a great solution for me. That's amazing I didn't know that was possible.
Problem with package.json being outside of rootDir solved by setting "rootDir": "./" and "baseUrl": "./src" in tsconfig.json
55

npm exports package.json attributes as env vars with the the prefix npm_package_ as described in npm docs
So if you're using npm you can get the version as process.env.npm_package_version

3 Comments

not in case of Vite! 😶
When running from under the VSCode debugger, there are no variables with the prefix: "npm_..."
I noticed that custom and many other package values don't appear attached to the environment variables.
23

Since TypeScript 2.9 you can import JSON files as described here: typescriptlang documentation 2.9#json, for this you need to enable the "resolveJsonModule" option in your tsconfig.json.

You need typescript version 2.9 in your project:

npm i typescript@latest --save or yarn add typescript

if you are building the typescript files from the command line with tsc, you will need to install the latest typescript version globally:

npm i -g typescript@latest or yarn global add typescript

if you are building your project with webpack and webpack-dev-server you need to make sure that json files are hosted in the webpack-dev-server context as static files. And even if you hosted them, you can't import json files in the web environment like this, you would need to load the json file with an ajax request and parse the response with JSON.parse.

2 Comments

Perfect, thanks. The only thing to note is that I had to include BOTH the resolveJsonModule option as well as esModuleInterop. Once I set those both to true it finally worked for me.
Adding resolveJsonModule to the tsconfig.json worked for me
14

Typescript should be able to do it as follows:

import * as pack from "../package.json"

// access name and version like this:

console.log(pack.name);

Check out the third grey box under Support for well-typed JSON imports.
https://blogs.msdn.microsoft.com/typescript/2018/05/31/announcing-typescript-2-9/#json-imports

2 Comments

The import name should not be "package" because it will return the following error: TS1213: Identifier expected. 'package' is a reserved word in strict mode. Class definitions are automatically in strict mode.
import * as pack from '../package.json'; should work
11
  1. Ensure tsconfig.json compiler options contains:

    "resolveJsonModule": true, "esModuleInterop": true, "module": "commonjs"

  2. Import package.json with typings

    import * as pack from '../package.json';

Comments

6

As Corey Jallen already said. But I had some issues with the * import because of the module property module.default. Also with JavaScript and native ESModules you can do the following:

import packageJson from "./package.json" with { type: "json"};

// Access properties of package.json
console.log(packageJson.name);

I added the with { type: "json"} because ESLint threw an error otherwise.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.