Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use Python’s built-in json module and an open() context manager:

import json

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

open() locates and reads the file, while json.load() parses one complete JSON document into Python data. No third-party package is required.

The simplest way to load a JSON file

import json

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

print(data)

The "r" mode is optional because reading is open()’s default. Specifying encoding="utf-8" makes the intended text encoding explicit. The with statement closes the file automatically, even when an error occurs. Python’s open() function returns a file object, and json.load() reads that object’s contents and deserializes them.

A complete example

Create data.json

{
  "name": "Ada",
  "age": 36,
  "languages": ["Python", "C"]
}

Read and use it

import json

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

print(person["name"])
print(person["age"])
print(person["languages"])

Output:

Ada
36
['Python', 'C']

A JSON object becomes a Python dict, so use string keys. A JSON array becomes a Python list, so use indexes or iterate over it:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
[
  {"name": "Ada", "active": true},
  {"name": "Grace", "active": false}
]
with open("users.json", encoding="utf-8") as file:
    users = json.load(file)

for user in users:
    print(user["name"], user["active"])

json.load() versus json.loads()

Function Input Typical use
json.load(file_object) An open file-like object with .read() Parse JSON directly from a file
json.loads(value) A JSON string, bytes, or bytearray Parse text already held in memory
import json

text = '{"name": "Ada"}'
data = json.loads(text)

This is not valid:

json.load("data.json")

A filename string is not a file object. Open the file first, or use Path.open(). In modern Python, json.loads() does not take an encoding keyword; choose the encoding when reading the file.

Load JSON with pathlib

import json
from pathlib import Path

path = Path("data.json")

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

Path.open() accepts the same important mode and encoding arguments as open(). For a small file, this shorter alternative reads all text first:

import json
from pathlib import Path

data = json.loads(Path("data.json").read_text(encoding="utf-8"))

Parsing from the open file avoids a separate full-text string and makes the file-versus-parser distinction clearer; read_text() is convenient for small configuration files.

What JSON values become in Python

JSON Python
object dict
array list
string str
number int or float
true/false True/False
null None

The top-level value can also be a string, number, boolean, or null; it does not have to be an object or array.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Fix common loading errors

FileNotFoundError

from pathlib import Path
import json

path = Path("data.json")

try:
    with path.open(encoding="utf-8") as file:
        data = json.load(file)
except FileNotFoundError:
    print(f"File not found: {path}")

A relative path is resolved from the process’s current working directory, not necessarily the directory containing your script. Check it with:

from pathlib import Path
print(Path.cwd())

To locate a file beside a regular script:

from pathlib import Path
import json

json_path = Path(__file__).resolve().parent / "data.json"
with json_path.open(encoding="utf-8") as file:
    data = json.load(file)

__file__ is normally available in a script, but not in every notebook or interactive environment.

Invalid JSON: JSONDecodeError

import json

try:
    with open("data.json", encoding="utf-8") as file:
        data = json.load(file)
except json.JSONDecodeError as error:
    print(f"Message: {error.msg}")
    print(f"Line: {error.lineno}, column: {error.colno}")
    print(f"Character position: {error.pos}")

JSONDecodeError is a ValueError subclass. Typical causes include:

  • Single quotes instead of JSON’s required double quotes: {"name": "Ada"}
  • Trailing commas, comments, or unquoted property names
  • Python literals such as True, False, or None instead of true, false, or null
  • An empty or truncated file
  • Two documents concatenated where one document is expected

Encoding errors and UTF-8 BOMs

JSON permits UTF-8, UTF-16, and UTF-32; UTF-8 is recommended for interoperability (RFC 8259). Use the encoding that produced the file:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
with open("data.json", encoding="utf-16") as file:
    data = json.load(file)

If software added a UTF-8 byte-order mark (BOM), Python can reject it. Try utf-8-sig as a recovery option, or regenerate the file without a BOM:

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

Valid syntax, wrong shape

Parsing does not enforce your application’s schema. Check the structure and types after loading:

if not isinstance(data, dict):
    raise TypeError("Expected a top-level JSON object")
if not isinstance(data.get("age"), int):
    raise TypeError("Expected age to be an integer")

Validate from the command line

python -m json.tool data.json

This standard-library command parses and pretty-prints valid JSON, or reports a location for a syntax error. To request two-space indentation:

python -m json.tool --indent 2 data.json

The --json-lines option parses one JSON value per line and was added in Python 3.8; command-line options vary across older Python releases. See the json.tool documentation.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

JSON Lines requires different code

Ordinary JSON contains one complete document, such as an array:

[
  {"id": 1},
  {"id": 2}
]

JSON Lines (NDJSON) contains one document on each line:

{"id": 1}
{"id": 2}

Calling json.load() on the second format generally raises an “extra data” error. For a small file:

import json

with open("events.jsonl", encoding="utf-8") as file:
    events = [json.loads(line) for line in file if line.strip()]

For larger files, process each line without collecting everything:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
import json

with open("events.jsonl", encoding="utf-8") as file:
    for line_number, line in enumerate(file, start=1):
        if not line.strip():
            continue
        try:
            event = json.loads(line)
        except json.JSONDecodeError as error:
            print(f"Invalid JSON on line {line_number}: {error}")
            continue
        process(event)

Large or untrusted files

json.load() parses one complete document and normally builds its Python representation in memory. The standard library does not provide general streaming for arbitrarily large nested JSON. Set input-size limits for attacker-controlled data: malicious JSON can consume substantial CPU or memory. Valid syntax also says nothing about acceptable keys, types, values, or business rules; add schema or application validation. Never use eval() to parse JSON.

For very large datasets, consider JSON Lines with incremental processing, a streaming parser, a database, or a columnar format. The Python implementation notes explain why application-level limits matter.

Useful advanced options

Preserve decimal precision

import json
from decimal import Decimal

with open("prices.json", encoding="utf-8") as file:
    prices = json.load(file, parse_float=Decimal)

Without this option, JSON decimals become Python float values.

Build custom objects

def as_user(obj):
    if "name" in obj and "email" in obj:
        return User(name=obj["name"], email=obj["email"])
    return obj

with open("users.json", encoding="utf-8") as file:
    users = json.load(file, object_hook=as_user)

object_hook is optional; ordinary JSON objects become dictionaries.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Reject non-standard numbers

import json

def reject_nonstandard_number(value):
    raise ValueError(f"Non-standard JSON number: {value}")

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

Python accepts NaN, Infinity, and -Infinity by default, although they are outside standard JSON number syntax.

A reusable loader with clear errors

import json
from pathlib import Path

def load_json(path: str | Path):
    path = Path(path)
    try:
        with path.open(encoding="utf-8") as file:
            return json.load(file)
    except FileNotFoundError:
        raise RuntimeError(f"JSON file does not exist: {path}") from None
    except json.JSONDecodeError as error:
        raise RuntimeError(
            f"Invalid JSON in {path} at line {error.lineno}, "
            f"column {error.colno}: {error.msg}"
        ) from error

Choose separately whether a missing optional file should return a fallback, whether invalid configuration should stop startup, and where the original exception should be logged. Avoid a bare except:, which can hide unrelated programming errors.

Quick reference

import json

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

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.