355

I would like to include a couple of JSON files in my JavaScript code that are in the same directory as my JavaScript source file.

If I wanted to include another JavaScript file I could simply use require. Now I'm using readFileSync and __dirname to get the JSON, which I think is an ugly way to do it.

Is there something similar for require that enables me to load a JSON file?

Kirill
  • 2,590
  • 1
  • 17
  • 16
Corno
  • 5,448
  • 4
  • 25
  • 41
  • See this similar question: http://stackoverflow.com/questions/4662851/how-do-you-import-non-node-js-files – holygeek Aug 23 '11 at 15:01
  • @coen What do you mean by "include a JSON file"? Read and parse it? If yes, possible duplicate of: http://stackoverflow.com/questions/5726729/how-to-parse-json-using-nodejs – Ciro Santilli OurBigBook.com Jun 14 '14 at 12:20
  • 3
    yes; read and parse. But this is specifically reading a *file*, similar to reading a js file, so this is no duplicate and goatslacker's answer is still valid. – Corno Jun 15 '14 at 18:23

10 Answers10

605

As of node v0.5.x yes you can require your JSON just as you would require a js file.

var someObject = require('./somefile.json')

In ES6:

import someObject from './somefile.json'
Wallace Sidhrée
  • 11,221
  • 6
  • 47
  • 58
goatslacker
  • 10,032
  • 2
  • 15
  • 15
  • 2
    Is this true? It's not working for me, and https://github.com/joyent/node/issues/1357 and https://github.com/joyent/node/pull/584 suggest it shouldn't. – user161642 Oct 19 '12 at 19:38
  • those two tickets are 1 and 2 years old. JSON require was added in node 0.5. – goatslacker Oct 19 '12 at 20:20
  • 15
    You need to use require('./somefile.json') assuming the file is in the same directory (note the dot and slash). – Steve Willcock May 30 '13 at 21:19
  • 88
    There's one gotcha with this. The result will be cached! So if you for some reason need to load the data again (say at a cronjob), you'll get the same old result. – Juho Vepsäläinen Nov 18 '13 at 11:21
  • 1
    @bebraw I cannot seem to reproduce that on node 0.10.x, are you sure? – Camilo Martin Aug 14 '14 at 06:25
  • @CamiloMartin Yes, absolutely sure. Try creating some JSON file, load it through Node REPL, modify JSON and load again. It should yield the first results. – Juho Vepsäläinen Aug 14 '14 at 09:40
  • 1
    @bebraw Ah! But that's totally different, expected, and in compliance with the docs. I'm not going to use a `config.json` file as if it was a database, adding and removing stuff at run-time. But if I restart the server, all changes will be taken in at the next run - the same is true for all the javascript you're using; configuration is like variables in your code. – Camilo Martin Aug 14 '14 at 10:14
  • @CamiloMartin Yeah, it's alright to use `require` in that case. I agree. – Juho Vepsäläinen Aug 14 '14 at 13:46
  • 57
    Note : the extension `.json` seem to matter – nha Sep 02 '14 at 08:45
  • 14
    well formed json helps too – sdeburca May 14 '15 at 09:44
  • 8
    Just as a note, if you did want a different file other than `.json` to be parsed as json, you could teach require how to read it. `require.extensions['.har'] = require.extensions['.json']; var blar = require('./file.har');` will now be treated as json – WORMSS Mar 11 '20 at 09:08
  • Just to clarify this works the same for normal is imports in the sense the import is cached. Eg if I have a JSON file (a), file (b) references file (a). And file (c) references file (a) and(b). The (a) import will only be loaded once right ( same as normal as imports) using `import * from ./data-file-a.json` – Gweaths Feb 25 '21 at 22:40
  • With TS I was need to add flags: `--resolveJsonModule` `--esModuleInterop` – Elihai David Vanunu Nov 29 '22 at 15:36
70

JSON files don’t require an explicit exports statement. You don't need to export to use it as Javascript files.

So, you can use just require for valid JSON document.

data.json

{
  "name": "Freddie Mercury"
}

main.js

var obj = require('data.json');

console.log(obj.name); 
//Freddie Mercury
serkan
  • 6,885
  • 4
  • 41
  • 49
51

Two of the most common way to import

First way :

let jsonData = require('./JsonFile.json')

let jsonData = require('./JsonFile') // if we omitting .json also works

OR

import jsonData from ('./JsonFile.json')

Second way :

  1. synchronously

    const fs = require('fs')
    let jsonData = JSON.parse(fs.readFileSync('JsonFile.json', 'utf-8'))
    
  2. asynchronously

    const fs = require('fs')
    let jsonData = {}
    fs.readFile('JsonFile.json', 'utf-8', (err, data) => {
      if (err) throw err
    
      jsonData = JSON.parse(data)
    })
    

Note:

  1. If JsonFile.json is changed, we do not get the new data, even if we re-run require('./JsonFile.json')

  2. The fs.readFile or fs.readFileSync will always re-read the file, and get changes

JoSSte
  • 2,953
  • 6
  • 34
  • 54
Rajkumar
  • 1,017
  • 9
  • 12
  • 6
    Note that the fs method uses the directory where node was launched from as a starting point, not the directory where the source code doing the read resides, whereas the "require" method uses the path relative to the importing source code location. So you will have differences in paths between the two methods as soon as you store things in different folders. – Will59 Jan 06 '20 at 14:28
  • >> if we omitting .json also works << Better to not omit `.json`, because node will try to load `.js` file, so it can lead to bugs. – Ivan Pruchai Jul 06 '23 at 07:14
24

No. Either use readFile or readFileSync (The latter only at startup time).

Or use an existing library like

Alternatively write your config in a js file rather then a json file like

module.exports = {
  // json
}
Raynos
  • 166,823
  • 56
  • 351
  • 396
  • 1
    @coen yes, we always use `__dirname` to make relative paths. – Raynos Aug 23 '11 at 15:19
  • Ran into this where it will import JSON locally but not in the docker container on my EC2 instance in AWS... Instead of trying to configure mime types and what not, I just switched to JS instead of JSON. Hope this may help someone. – Erik Grosskurth Jul 23 '19 at 19:54
  • This answer is straight up incorrect, you should either update or remove it. – ThisGuyCantEven Sep 07 '22 at 16:24
10

A nifty non-caching async one liner for node 15 modules:

import { readFile } from 'fs/promises';

const data = await readFile('{{ path }}').then(json => JSON.parse(json)).catch(() => null);
som
  • 2,023
  • 30
  • 37
8

You can import json files by using the node.js v14 experimental json modules flag. More details here

file.js

import data from './folder/file.json' assert { type: 'json' }

export default {
  foo () {
    console.log(data)
  }
}

And you call it with node --experimental-json-modules file.js

dreamLo
  • 1,612
  • 12
  • 17
  • I got this error: `TypeError [ERR_IMPORT_ASSERTION_TYPE_MISSING]: Module "src/__tests__/operations.json" needs an import assertion of type "json"` – Serkan KONAKCI Sep 25 '22 at 15:35
7

You even can use require of your JSON without specifying the extension .json. It will let you change the file extension to .js without any changes in your imports.

assuming we have ./myJsonFile.json in the same directory.

const data = require('./myJsonFile')

If in the future you'll change ./myJsonFile.json to ./myJsonFile.js nothing should be changed in the import.

Igor Litvinovich
  • 2,436
  • 15
  • 23
  • This is confusing. Your proposed example of wanting to change the json require to a js require is a stretch of the imagination. Your answer should just stick to the facts and avoid the hypothetical scenario. I also suggest that your hypothetical filename `./myJsonFile.js` is confusing. Why would it be called "myJsonFile" if it has a .js extension? Additional useful fact though: if you do `require('./file')` and both `file.js` and `file.json` exist, then it will use `file.js`. – Wyck Feb 27 '21 at 16:07
  • Found useful that you may supress the file extension `.json`. Thnks – Manu Artero Sep 13 '22 at 14:55
2

You can use a module to create a require.

import { createRequire } from 'module'
const require = createRequire(import.meta.url)
const foo = require('./foo.json')
-1

Simply use the JSON object from Node; you don't need import it. See usage below:

const jsonifiedObject = JSON.parse(an_array or a_object)
or
JSON.stringify(object)

Hope that helps..

Chukwunazaekpere
  • 906
  • 1
  • 6
  • 13
  • The question was about getting the data from disk. Your solution is applicable when the data is already loaded – Corno Apr 17 '23 at 18:27
-2

if you are using typescript, you can just add in your tsconfig.json a new field called resolveJsonModule: true, and then you can import all the informations of any .json file just like this:

import * as jsonfile from "./path/to/json"