How to Read a JSON File in Python

JSON (JavaScript Object Notation) is one of the most common data formats you'll encounter when working with APIs, configuration files, databases, and web services. Python makes reading JSON files straightforward — but the right approach depends on your data structure, file size, and what you plan to do with the data afterward.

What Is a JSON File?

A JSON file stores data as structured text using key-value pairs, arrays, and nested objects. It's human-readable and language-agnostic, which is why it's become a universal standard for data exchange.

A typical JSON file might look like this:

{ "name": "Alice", "age": 30, "languages": ["Python", "JavaScript"], "active": true } 

Python's built-in json module handles this format natively — no installation required.

The Standard Way: Using Python's Built-in json Module

The most common method uses open() to read the file and json.load() to parse it into a Python object.

import json with open("data.json", "r") as file: data = json.load(file) print(data) 

What's happening here:

  • import json loads Python's built-in JSON library
  • open("data.json", "r") opens the file in read mode
  • json.load(file) parses the file contents and returns a Python dictionary (or list, depending on the JSON structure)
  • The with statement automatically closes the file after reading — always preferred over manually calling file.close()

Once loaded, you access values just like any Python dictionary:

print(data["name"]) # Output: Alice print(data["languages"][0]) # Output: Python 

JSON to Python: How Types Are Mapped 🗂️

Understanding how JSON types convert to Python types prevents a lot of confusion:

JSON TypePython Type
object{}dict
array[]list
string""str
number (int)int
number (float)float
true / falseTrue / False
nullNone

This mapping is automatic — json.load() handles the conversion without any extra steps.

Reading a JSON String Instead of a File

If your JSON data is already in memory as a string (common when receiving API responses), use json.loads() instead — the s stands for string:

import json json_string = '{"name": "Alice", "age": 30}' data = json.loads(json_string) print(data["age"]) # Output: 30 

The distinction matters:

  • json.load() — reads from a file object
  • json.loads() — reads from a string

Handling Encoding and File Paths

Specifying Encoding

If your JSON file contains non-ASCII characters (accented letters, Unicode symbols, etc.), specify the encoding explicitly:

with open("data.json", "r", encoding="utf-8") as file: data = json.load(file) 

UTF-8 is the standard encoding for JSON files per the JSON specification, but files created on Windows systems sometimes use other encodings. Omitting this argument on some systems can cause UnicodeDecodeError.

Using File Paths

For files in different directories, pass the full or relative path:

with open("/users/alice/documents/data.json", "r") as file: data = json.load(file) 

Using Python's pathlib module gives you more flexibility across operating systems:

from pathlib import Path import json file_path = Path("data") / "config.json" with open(file_path, "r") as file: data = json.load(file) 

Reading JSON Files with Nested Structures

Real-world JSON is often nested — objects inside objects, or lists of objects. Accessing nested values requires chaining keys and indexes:

{ "user": { "profile": { "city": "Toronto" } } } 
city = data["user"]["profile"]["city"] print(city) # Output: Toronto 

For deeply nested or inconsistent data, .get() is safer than direct key access because it returns None instead of raising a KeyError if a key doesn't exist:

city = data.get("user", {}).get("profile", {}).get("city", "Unknown") 

Handling Errors When Reading JSON

Two common errors appear when reading JSON files:

FileNotFoundError — the file path is wrong or the file doesn't exist:

try: with open("data.json", "r") as file: data = json.load(file) except FileNotFoundError: print("File not found. Check the path.") 

json.JSONDecodeError — the file content isn't valid JSON (trailing commas, missing quotes, and comments are common culprits):

try: with open("data.json", "r") as file: data = json.load(file) except json.JSONDecodeError as e: print(f"Invalid JSON: {e}") 

When the Standard Approach Isn't Enough

For most use cases — reading config files, processing API responses, loading small datasets — the built-in json module is all you need.

But the variables in your project may push you toward different tools:

  • Large JSON files (hundreds of MB or more) can exhaust memory with json.load(). Libraries like ijson allow streaming — parsing the file incrementally without loading everything at once.
  • Tabular JSON data (lists of records with consistent keys) is often better handled by pandas using pd.read_json(), which loads data directly into a DataFrame for analysis.
  • Strict schema validation requirements call for libraries like jsonschema, which verify that loaded data matches an expected structure before your code processes it.
  • JSONL files (JSON Lines format, where each line is a separate JSON object) require reading line by line rather than loading the whole file.

The right tool shifts depending on file size, data shape, downstream processing needs, and how much control you need over error handling. What works cleanly for a 10KB config file may create serious problems when applied to a 2GB data export. 🔍