dataclasses-json: Practical JSON Serialization for Python Dataclasses
Easily serialize Data Classes to and from JSON
At a glance
- What is it?
- dataclasses-json adds JSON conversion and optional Marshmallow validation to Python dataclasses through either a decorator or a mixin. It fits applications that already model structured data with dataclasses, but its default conversions and schema setup require attention.
- Who is it for?
- Adopt dataclasses-json when your Python application already uses dataclasses and needs JSON conversion with optional Marshmallow validation, especially if its field types and naming conventions fit the library defaults. Do not adopt it when automatic runtime type validation is required from `from_json`, lossless datetime round trips are mandatory, or an unsupported custom type needs behavior that the documentation does not explain.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Activity is slowing. The repository last received commits 6 months ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on November 7, 2026, and from our analysis. They are not legal advice.
Star history
- lidatong/dataclasses-json1,488 ★ · +0
| Repository | 2026-10-19 | 2026-11-07 |
|---|---|---|
| lidatong/dataclasses-json | 1.5k | 1.5k |
0 Stars in the last 19 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
Why dataclasses-json Exists for Dataclass-Based APIs
dataclasses-json addresses a specific gap between Python dataclasses and JSON APIs: dataclasses describe application data as typed class instances, while `json.dumps` expects values that it recognizes, such as dictionaries, lists, strings, numbers, booleans, and null. Converting every field by hand is repetitive, especially when an API response contains nested dataclasses or arrays of dataclass instances.
The library targets Python developers who want to keep dataclasses as their application model and use methods such as `to_json()`, `to_dict()`, `from_json()`, and `from_dict()`. It also provides a schema API that can validate values through Marshmallow. This makes it relevant to command-line programs, service clients, configuration processors, and internal APIs whose payloads are structured around Python dataclass definitions.
Its scope is serialization, deserialization, naming configuration, and optional validation. It is not a complete API client, HTTP framework, persistence layer, or schema-management service. The value is narrower: it removes repeated conversion code while preserving dataclass instances at application boundaries. That narrow purpose is useful when standard JSON structures fit the library's supported type model, but it also means applications with unusual serialization requirements will still need custom logic.
How dataclasses-json Converts Dataclass Values
The README documents two integration styles. The decorator approach adds conversion methods to a dataclass, while the mixin approach places the same runtime interface in a base class. Both expose instance and class-level operations for JSON strings and Python dictionaries.
A `Person` dataclass can call `to_json()` to produce a JSON string and `to_dict()` to produce a dictionary. The corresponding decoding path is `Person.from_json()` and `Person.from_dict()`. These dictionary methods matter when a dataclass is only one part of a larger document. In that case, `to_dict()` can place the converted class inside a response structure, and the standard library's `json.dumps()` can serialize the outer object. Decoding follows the reverse pattern with `json.loads()` and `from_dict()`.
The schema interface exposes operations such as `dump()`, `load()`, `dumps()`, and `loads()`. Schema methods also support a `many=True` argument for collections. The dependency declaration includes Marshmallow, which is the validation-oriented layer behind the alternative schema API. This distinction is important because the convenience methods do not all enforce the same type rules. The README states that `from_json('{"name": 42}')` accepts an integer for a field annotated as `str`, since ordinary dataclass creation does not validate types. In contrast, `Person.schema().loads('{"name": 42}')` raises `ValidationError`.
Nested dataclasses and collections are supported recursively, subject to the caveats discussed below. The repository therefore offers a compact conversion layer, but it does not replace an application-level contract review when incoming data can be malformed or ambiguous.
Installing and Using the Decorator API
The documented installation command installs the package from PyPI. The example then defines a dataclass, applies `@dataclass_json` above `@dataclass`, and exercises both serialization and deserialization.
The decorator order is explicit in the README: `@dataclass_json` must be stacked above `@dataclass`. After installation, the following is the first complete use documented by the project:
pip install dataclasses-jsonThe reader should see a successful installation in the active Python environment. The README states that the latest release is compatible with Python 3.7 and Python 3.6 when the dataclasses backport is used. The package declaration requires Python `^3.7` and depends on `typing-inspect` and Marshmallow.
Define and convert a simple class with the following code:
from dataclasses import dataclass
from dataclasses_json import dataclass_json
@dataclass_json
@dataclass
class Person:
name: str
person = Person(name='lidatong')
person.to_json()
person.to_dict()
Person.from_json('{"name": "lidatong"}')
Person.from_dict({'name': 'lidatong'})The documented return values are a JSON string, a dictionary, and `Person` instances. The decorator should not be placed below `@dataclass`, because the README says that order matters.
For data embedded in a larger object, serialize the dataclass first and pass the surrounding dictionary to the built-in JSON module. This avoids forcing the entire application response through one schema when only part of it contains dataclass instances.
Choosing DataClassJsonMixin for Typing Tool Support
The mixin approach offers the same documented runtime usage as the decorator, but it makes the relationship between the dataclass and its conversion methods visible through inheritance. That can be easier for static analysis tools to understand.
Use the mixin as follows:
from dataclasses import dataclass
from dataclasses_json import DataClassJsonMixin
@dataclass
class Person(DataClassJsonMixin):
name: str
lidatong = Person('lidatong')
assert Person.from_json(lidatong.to_json()) == lidatongThe assertion represents the equality check given in the README. The documented methods remain `to_json()`, `to_dict()`, `Person.from_json()`, and `Person.from_dict()`.
The choice is therefore not based on different serialization rules. It is based on class design and tooling compatibility. The README says there is better static analysis support for the mixin approach, especially for linting and typing, and describes runtime differences as invisible. Projects that prefer explicit base classes may find the inheritance model clearer, while projects that want to keep the dataclass declaration free of a base class can use the decorator.
Neither style fixes the validation distinction between convenience methods and schema methods. Code that needs field validation must use the schema API explicitly. Selecting the mixin because it improves static analysis support should not be confused with adding runtime validation to `from_json()`.
Field Names, Nested Data, and Supported Type Boundaries
The library can map Python field names to camelCase JSON keys through `LetterCase.CAMEL`. The decorator receives the naming configuration, after which fields such as `int_field` are encoded as `intField`. This is useful for APIs whose JSON contract uses camelCase while the Python model uses snake_case.
from dataclasses import dataclass
from dataclasses_json import dataclass_json, LetterCase
@dataclass_json(letter_case=LetterCase.CAMEL)
@dataclass
class ConfiguredSimpleExample:
int_field: int
ConfiguredSimpleExample(1).to_json()
ConfiguredSimpleExample.from_json('{"intField": 1}')The README says support is recursive, including nested dataclasses and collections. Mappings become JSON objects, `str` collections become JSON strings, and other supported collections become JSON arrays while retaining their collection type during decoding. `UUID` and `Decimal` values become JSON strings. These rules are convenient, but they also define a serialization contract that should be tested against an actual API.
`datetime` is the clearest boundary. It is encoded as a JSON number by calling `timestamp()`, and decoded into a timezone-aware object using the system local timezone. A naive datetime is interpreted using the local timezone when encoded. Consequently, a naive value can return as an aware value after decoding, so the operation is not a strict inverse. The README points to its overriding documentation for applications that prefer alternatives such as ISO-formatted dates.
The project is therefore a poor fit for code that requires every JSON field to be validated by `from_json()`, or for a contract where naive and aware datetimes must survive a round trip unchanged without configuration.
Maintenance, Dependencies, and Upgrade Boundaries
The repository uses Poetry and declares `typing-inspect` with a range from `0.4.0` to below `1`, plus `marshmallow` with a range from `3.18.0` to below `4.0.0`. The build configuration uses `poetry-core>=1.2.0` and `poetry-dynamic-versioning`. Those constraints give consumers concrete compatibility boundaries instead of leaving all dependency handling to an application.
The package metadata places the project under the MIT license. That permits use and modification under the license terms, while redistribution and distribution still require attention to the full license text and notices. This is a technical adoption consideration, not legal advice.
The repository is not archived, and the last push was on 2026-05-05. The recent release list includes v0.6.7 from 2024-06-09, followed by v0.6.6 and v0.6.5 in May and April 2024. The gap between the listed release dates and the last push means repository activity and published package availability should not be treated as the same fact. Upgrading requires reviewing Marshmallow compatibility, Python version support, and any custom field behavior already present in the application.
The README does not document a long-term support policy or a compatibility matrix for every intermediate Python release. It points to the releases page for changelog information. For an existing integration, the most relevant upgrade check is whether current code relies on the documented default behavior, especially schema validation, camelCase conversion, and datetime encoding.
Editorial conclusion
Adopt dataclasses-json when your Python application already uses dataclasses and needs JSON conversion with optional Marshmallow validation, especially if its field types and naming conventions fit the library defaults. Do not adopt it when automatic runtime type validation is required from `from_json`, lossless datetime round trips are mandatory, or an unsupported custom type needs behavior that the documentation does not explain. Before adoption, verify the exact serialization of nested dataclasses, collections, `datetime`, `UUID`, and `Decimal` values against your payloads, then test the selected decorator or mixin with the Python version used in production. The repository's last push was on 2026-05-05, while its most recent listed release, v0.6.7, dates to 2024-06-09, so compatibility and release expectations should be checked explicitly.
Frequently asked questions
How do I install and use dataclasses-json with a Python dataclass?
Install it with `pip install dataclasses-json`, then stack `@dataclass_json` above `@dataclass` or inherit from `DataClassJsonMixin`. The resulting class supports `to_json()`, `to_dict()`, `from_json()`, and `from_dict()`.
Does dataclasses-json validate field types with from_json()?
No. The README explains that `from_json()` can accept a value that conflicts with the dataclass annotation because dataclass creation does not validate types. Use `Person.schema().loads(...)` when Marshmallow `ValidationError` behavior is required.
Does dataclasses-json preserve naive datetime objects after a round trip?
Not strictly. A naive `datetime` is encoded with `timestamp()`, and decoding produces a timezone-aware object using the system local timezone. The README points to its overriding documentation for alternatives such as ISO formatting.
Can dataclasses-json encode a dataclass inside a larger JSON object?
Yes. Convert the dataclass with `to_dict()`, place that dictionary inside a larger structure, and use Python's built-in `json.dumps()` to encode the complete object. Reverse the process with `json.loads()` and `from_dict()`.
Can dataclasses-json use camelCase JSON keys?
Yes. Pass `LetterCase.CAMEL` to `@dataclass_json(letter_case=LetterCase.CAMEL)`. The README shows `int_field` being encoded and decoded as `intField`.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/lidatong-dataclasses-json)Star history chart for your README
[](https://hysenlabs.com/projects/lidatong-dataclasses-json)Was this useful?