Introduction
cJSON is one of the smallest and most portable JSON parsers available for C. Written in ANSI C89 with no dependencies, it compiles on virtually any platform including microcontrollers with limited memory. Its tree-based API makes building, parsing, and modifying JSON structures straightforward.
What cJSON Does
- Parses JSON text into a linked-list tree of typed nodes
- Prints JSON trees back to formatted or minified text strings
- Creates JSON objects and arrays programmatically with a builder API
- Handles nested structures, numbers, strings, booleans, and null values
- Provides both malloc-based and custom-allocator memory management
Architecture Overview
cJSON represents JSON as a doubly-linked tree of cJSON structs. Each node holds a type tag, a string key (for object members), and a value (string pointer, double, or child pointer). Parsing is a single recursive-descent pass. Printing walks the tree and writes to a dynamically grown buffer. The entire implementation fits in one .c file (~1500 lines including comments).
Self-Hosting & Configuration
- Drop
cJSON.candcJSON.hinto your project — no build system required - Optional CMake build for shared/static library and
pkg-configsupport - Override
mallocandfreeviacJSON_InitHooks()for custom allocators - Compile with
-DCJSON_NESTING_LIMIT=512to control max parse depth - Works with any C89 compiler: GCC, Clang, MSVC, TinyCC, and embedded toolchains
Key Features
- Under 1500 lines of C code with zero external dependencies
- Runs on 8-bit microcontrollers (Arduino, ESP8266) and mainframes alike
- Stable API that has not broken backward compatibility in over a decade
- Bundled test suite with over 200 test cases
- MIT licensed and widely vendored in firmware and OS projects
Comparison with Similar Tools
- nlohmann/json — C++ only, much larger; cJSON is pure C and far smaller
- jsmn (Jasmine) — zero-allocation tokenizer but no tree API or printer
- yyjson — faster parsing with SIMD but requires C99 and is more complex
- Jansson — full-featured C JSON library but 5x larger codebase
- parson — similar size and API style but slightly less portable
FAQ
Q: Is cJSON safe to use with untrusted input?
A: cJSON has been fuzzed and battle-tested. Set CJSON_NESTING_LIMIT to prevent stack exhaustion on deeply nested input, and always check cJSON_Parse return values.
Q: Can I use cJSON in C++ projects?
A: Yes. The header is extern "C" compatible. For idiomatic C++ you may prefer nlohmann/json, but cJSON works fine when called from C++ code.
Q: How does memory management work?
A: cJSON_Parse allocates a tree using malloc. Call cJSON_Delete on the root when done. You can substitute custom allocators via cJSON_InitHooks.
Q: What is the maximum JSON size cJSON can handle? A: Limited only by available memory. For multi-gigabyte files, consider a streaming parser like yyjson; cJSON loads the entire tree into memory.