How to import JSON files in ES modules
- Published at
- Updated at
- Reading time
- 2min
If you're using ECMAScript modules, you probably know the problem — you can't "just" import JSON files. To import and load a JSON file in browser ES modules, you have to do a "window
dance" and request the JSON file to parse it yourself. It's terrible...
There were multiple attempts to resolve this poor DX and make it easier to load JSON. Let's find out where we stand today!
Chrome started off with JSON Modules shipping in Chrome 91.
// Legacy: JSON modules
import data from "./resource.json"
The idea was to rely on the returned resource MIME type to evaluate how a module file should be handled. Imported resources of type application/json
or text/json
would then be parsed as JSON.
Unfortunately, this approach came with a hard-to-ignore security flaw. What if a harmless-looking resource
returns the text/javascript
MIME type, and the browser starts executing this static file? This approach is way too easy to exploit. Back to the drawing board!
To not only rely on content types, the next iteration were Import Assertions. With them, developers were responsible for defining the module type.
// Legacy: Import Assertions
import data from "./resource.json" assert { type: "json" };
And again, this feature shipped in Chromium land.
91 | 91 | 91 | Nö | Nope | Non | Nei | 16.0 | 91 |
But spec making is hard. Another discussion unveiled that bringing JSON loading to the web isn't only about parsing a resource in a JavaScript engine but also integrating the new functionality in other browser areas.
For example, how could asserted JSON requests be secured via CSP? And would a JSON import count as CSP connect-src
or script-src
? Import assertions weren't conceptualized for these challenges.
Eventually, things got sorted, and spec makers landed on reframing Import Assertions to Import Attributes and it seems to be the final option.
// Current proposal: Import Attributes
import data from "./resource.json" with { type: "json" };
Where are we support-wise?
After this back and forth, browsers don't really support the import attribute syntax at the time of writing.
123 | 123 | 123 | Nö | Nö | 17.2 | 17.2 | 27.0 | 123 |
So, for now, we're still stuck on fetching and parsing JSON manually. Maybe in 2024, we can just import some juicy JSON. That would be something.
Join 5.5k readers and learn something new every week with Web Weekly.