jsonlite fromJSON() in R: Parse JSON Into R Objects
The jsonlite fromJSON() function parses JSON into native R objects. It reads a JSON string, file path, or URL and returns a list, vector, or data frame, automatically simplifying the structure where it can.
fromJSON('{"a":1,"b":2}') # JSON object to a named list
fromJSON('[1,2,3]') # JSON array to an atomic vector
fromJSON('[{"x":1},{"x":2}]') # array of objects to a data frame
fromJSON(txt, simplifyVector = FALSE) # keep everything as nested lists
fromJSON(txt, flatten = TRUE) # flatten nested data frame columns
fromJSON("data.json") # parse a JSON file by path
fromJSON("https://api.example.com/data") # parse JSON straight from a URLNeed explanation? Read on for examples and pitfalls.
What fromJSON() does
fromJSON() converts JSON text into the closest matching R object. You pass it JSON and it returns a list, an atomic vector, or a data frame, depending on the shape of the input. The argument can be a literal JSON string, a path to a .json file, or an http:// URL, and fromJSON() detects which one it received.
The function does more than a literal translation. By default it runs a simplification step that turns JSON arrays into vectors and arrays of flat objects into data frames. That mapping makes jsonlite practical: API responses arrive as nested JSON, and fromJSON() lands them as a tidy data frame.
Syntax and key arguments
Most calls pass only the JSON itself; the remaining arguments control how aggressively fromJSON() simplifies the result. Web APIs return predictable shapes, so once you know the structure you can tune these flags to get exactly the object you want.
The three simplify* arguments all default to the value of simplifyVector, so setting simplifyVector = FALSE turns off simplification entirely and returns raw nested lists. The flatten argument is separate: it leaves simplification on but unpacks nested data frame columns into dotted column names like loc.lat.
pandas.read_json(), which also maps a JSON array of objects to a tabular structure. fromJSON() differs by returning either a base R data frame or a plain list, and you choose the shape with the simplify* flags rather than an orient argument.fromJSON() examples
Every example below uses a literal JSON string, so each block runs on its own with no file or network access. Start by loading jsonlite, then parse a simple JSON object.
A JSON object has named keys but no tabular shape, so fromJSON() returns a named list. JSON true becomes R TRUE, and the numeric value stays numeric.
An array of flat objects is the case fromJSON() simplifies into a data frame. This is the typical shape of an API result: a list of records that all share the same keys.
Turn simplification off with simplifyVector = FALSE when you want the raw structure. This is useful for ragged JSON where records do not share the same keys, since forcing a data frame would misalign the columns.
Use flatten = TRUE when records contain nested objects. Without it, a nested object becomes a data frame column that holds another data frame, which is awkward to index.
prettify() to see the indented structure, or call toJSON(x, pretty = TRUE) on a parsed object. Seeing the nesting makes it obvious whether you need flatten = TRUE.fromJSON() vs read_json(), parse_json() and toJSON()
fromJSON() is one of several jsonlite functions, and the right choice depends on your input and how much simplification you want. They share an engine, so the difference is mostly behaviour at the edges.
| Function | Direction | Simplifies? | Best for |
|---|---|---|---|
fromJSON() |
JSON to R | Yes, by default | Strings, files, or URLs you want as data frames |
read_json() |
JSON file to R | No, by default | A file path, kept as nested lists |
parse_json() |
JSON string to R | No | A literal string, kept exactly as written |
toJSON() |
R to JSON | n/a | Writing an R object back out as JSON |
stream_in() |
NDJSON to R | Yes | Large line-delimited JSON files |
Use fromJSON() when you want JSON converted into the most convenient R object with the least code. Reach for read_json() or parse_json() when you need the literal structure preserved, for example when keys vary between records. Use toJSON() for the reverse trip.
simplifyVector or flatten argument, not a manual loop to reshape the output.Common pitfalls
Passing malformed JSON. fromJSON() validates the text before parsing, so a missing value, an extra comma, or an unclosed brace stops it with a lexical error that names the position.
Using single quotes inside the JSON. The JSON standard requires double quotes around every key and string. A string like "{'a': 1}" is valid R but invalid JSON, and fromJSON() rejects it. Keep the outer R quotes single and the inner JSON quotes double.
Expecting a data frame from ragged records. fromJSON() builds a data frame only when the objects in an array share their keys. If some records miss a key, simplification fills the gaps with NA, hiding the fact that the source data is inconsistent.
txt looks like a URL, fromJSON() fetches it over the network. In a restricted environment that call fails or hangs. Download the file first, or parse a literal string, when you need a result that does not depend on connectivity.Try it yourself
Try it: Parse the JSON array below into a data frame, then compute the mean of the score column. Save the result to ex_mean.
Click to reveal solution
Explanation: The JSON array of flat objects simplifies to a data frame, so ex_df$score is an ordinary numeric column that mean() summarises directly.
Related jsonlite functions
fromJSON() sits in a small family of jsonlite functions for moving data between JSON and R. Pick the one that matches the direction you need and how much structure you want preserved.
toJSON(): serialize an R object back into a JSON string, the inverse of fromJSON().read_json(): read a JSON file by path, without simplification by default.write_json(): write an R object straight to a.jsonfile on disk.parse_json(): parse a literal JSON string while keeping the exact nested structure.stream_in(): read large newline-delimited JSON (NDJSON) one record at a time.prettify(): re-indent a JSON string so you can read its structure.validate(): check whether a string is well-formed JSON before parsing.
For the full argument reference, see the jsonlite fromJSON() documentation on CRAN.
FAQ
How do I read a JSON file in R?
Install jsonlite with install.packages("jsonlite"), load it with library(jsonlite), then call fromJSON("path/to/file.json"). The function detects that the argument is a file path, reads the file, and returns the parsed object. The path can be absolute or relative to your working directory.
What is the difference between fromJSON and read_json?
Both parse JSON, but they differ in defaults. fromJSON() accepts a string, file path, or URL and simplifies the result into vectors and data frames by default. read_json() is meant for file paths and returns the literal nested-list structure with no simplification. Use fromJSON() when you want a tidy data frame with minimal code, and read_json() when the exact structure matters or records have varying keys.
How do I convert JSON to a data frame in R?
Pass a JSON array of flat objects to fromJSON(). When every object in the array shares the same keys, the default simplifyDataFrame = TRUE collapses the array into a data frame with one row per object and one column per key. If the JSON contains nested objects, add flatten = TRUE so the nested fields become dotted columns instead of list-columns.
Why does fromJSON return a list instead of a data frame?
fromJSON() returns a data frame only for a JSON array of objects that share their keys. A single JSON object becomes a named list, and an array whose elements have different shapes stays a list because no consistent table exists. Check the JSON shape, and if you expected a table, confirm the input is an array [ ... ] of objects rather than one object { ... }.
Can fromJSON read JSON directly from a URL?
Yes. When the txt argument starts with http:// or https://, fromJSON() fetches the content over the network and parses the response in one step. This needs a live internet connection, so in an offline environment, download the file first and parse it locally.