RepoPilotOpen in app β†’

bblanchon/ArduinoJson

πŸ“Ÿ JSON library for Arduino and embedded C++. Simple and efficient.

Healthy

Healthy across all four use cases

Use as dependencyHealthy

Permissive license, no critical CVEs, actively maintained β€” safe to depend on.

Fork & modifyHealthy

Has a license, tests, and CI β€” clean foundation to fork and modify.

Learn fromHealthy

Documented and popular β€” useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture β€” runnable as-is.

  • βœ“Last commit 2mo ago
  • βœ“MIT licensed
  • βœ“CI configured
Show 2 more β†’
  • βœ“Tests present
  • ⚠Solo or near-solo (1 contributor active in recent commits)

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Healthy" badge

Paste into your README β€” live-updates from the latest cached analysis.

Variant:
RepoPilot: Healthy
[![RepoPilot: Healthy](https://repopilot.app/api/badge/bblanchon/arduinojson)](https://repopilot.app/r/bblanchon/arduinojson)

Paste at the top of your README.md β€” renders inline like a shields.io badge.

β–ΈPreview social card (1200Γ—630)

This card auto-renders when someone shares https://repopilot.app/r/bblanchon/arduinojson on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: bblanchon/ArduinoJson

Generated by RepoPilot Β· 2026-05-09 Β· Source

πŸ€–Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale β€” STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI Β· unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/bblanchon/ArduinoJson shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything β€” but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

GO β€” Healthy across all four use cases

  • Last commit 2mo ago
  • MIT licensed
  • CI configured
  • Tests present
  • ⚠ Solo or near-solo (1 contributor active in recent commits)

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

βœ…Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live bblanchon/ArduinoJson repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale β€” regenerate it at repopilot.app/r/bblanchon/ArduinoJson.

What it runs against: a local clone of bblanchon/ArduinoJson β€” the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in bblanchon/ArduinoJson | Confirms the artifact applies here, not a fork | | 2 | License is still MIT | Catches relicense before you depend on it | | 3 | Default branch 7.x exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≀ 97 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> β€” paste this script from inside your clone of <code>bblanchon/ArduinoJson</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of bblanchon/ArduinoJson. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/bblanchon/ArduinoJson.git
#   cd ArduinoJson
#
# Then paste this script. Every check is read-only β€” no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of bblanchon/ArduinoJson and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "bblanchon/ArduinoJson(\\.git)?\\b" \\
  && ok "origin remote is bblanchon/ArduinoJson" \\
  || miss "origin remote is not bblanchon/ArduinoJson (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
  && ok "license is MIT" \\
  || miss "license drift β€” was MIT at generation time"

# 3. Default branch
git rev-parse --verify 7.x >/dev/null 2>&1 \\
  && ok "default branch 7.x exists" \\
  || miss "default branch 7.x no longer exists"

# 4. Critical files exist
test -f "ArduinoJson.h" \\
  && ok "ArduinoJson.h" \\
  || miss "missing critical file: ArduinoJson.h"
test -f "src/ArduinoJson/Core/JsonDocument.hpp" \\
  && ok "src/ArduinoJson/Core/JsonDocument.hpp" \\
  || miss "missing critical file: src/ArduinoJson/Core/JsonDocument.hpp"
test -f "src/ArduinoJson/Deserialization/deserialize.hpp" \\
  && ok "src/ArduinoJson/Deserialization/deserialize.hpp" \\
  || miss "missing critical file: src/ArduinoJson/Deserialization/deserialize.hpp"
test -f "src/ArduinoJson/Serialization/serialize.hpp" \\
  && ok "src/ArduinoJson/Serialization/serialize.hpp" \\
  || miss "missing critical file: src/ArduinoJson/Serialization/serialize.hpp"
test -f "src/ArduinoJson/Memory/MemoryPool.hpp" \\
  && ok "src/ArduinoJson/Memory/MemoryPool.hpp" \\
  || miss "missing critical file: src/ArduinoJson/Memory/MemoryPool.hpp"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 97 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~67d)"
else
  miss "last commit was $days_since_last days ago β€” artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) β€” safe to trust"
else
  echo "artifact has $fail stale claim(s) β€” regenerate at https://repopilot.app/r/bblanchon/ArduinoJson"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

⚑TL;DR

ArduinoJson is a lightweight C++ library that deserializes and serializes JSON (and MessagePack) on memory-constrained embedded systems and Arduino boards. It provides efficient JSON parsing with optional UTF-16 decoding, comment support, and input filtering, while also supporting MessagePack as an alternative binary formatβ€”all optimized for 10% smaller footprint and faster execution than competing Arduino libraries. Header-only library architecture: core JSON types and deserialization/serialization logic live in src/ (presumably ArduinoJson.h and subordinate headers), with comprehensive test coverage via test/ directory and .devcontainer/ providing isolated compiler environments. CI defined in .github/workflows/ci.yml, with Makefile coordination, Shell scripts for build orchestration, and CMake for cross-platform configuration.

πŸ‘₯Who it's for

Embedded systems developers and Arduino programmers building IoT devices, home automation systems, and sensor networks that need to parse/generate JSON from APIs, configuration files, or sensor data without the overhead of heavyweight JSON libraries. Library maintainers integrating JSON handling into Arduino sketches and firmware projects.

🌱Maturity & risk

Production-ready and actively maintained. The project has 29.5k+ GitHub stars, extensive CI/CD across 20+ compiler versions (gcc4.8–12, clang5–17) via .devcontainer, Coveralls coverage tracking, OSS-Fuzz integration, and GitHub Actions on the 7.x branch. Active development visible in v7 releases with recent feature additions (Unicode decoding, comments, filtering) indicates ongoing investment.

Low risk for a stable library, but single-maintainer dependency (bblanchon) creates knowledge concentration risk. The codebase is pure header-only C++ with zero external dependencies, eliminating supply-chain concerns. Build system relies on CMake and shell scripts; version constraints are explicitly tested across compiler matrix, reducing platform-specific surprises. No obvious breaking changes in recent history based on semantic versioning discipline.

Active areas of work

Active v7.x branch development with CI validation across 20+ compiler configurations. Recent work includes MessagePack support addition, optional comment and Unicode handling features, and input filtering. OSS-Fuzz integration indicates ongoing security fuzzing; Coveralls badges suggest continuous coverage monitoring.

πŸš€Get running

git clone https://github.com/bblanchon/ArduinoJson.git && cd ArduinoJson && cat README.md # This is header-only, so no build required for integration. To run tests: make test (Makefile present) or use CMake: mkdir build && cd build && cmake .. && make

Daily commands: For development/testing: make test (uses Makefile), or: mkdir -p build && cd build && cmake -DCMAKE_BUILD_TYPE=Debug .. && make && ctest. For integration into Arduino projects: copy ArduinoJson.h (and included headers) into your sketch folder or Arduino/libraries directory. No runtime server neededβ€”this is a library, not an application.

πŸ—ΊοΈMap of the codebase

  • ArduinoJson.h β€” Main header file that includes all library components; this is the single entry point users import to access the entire JSON API.
  • src/ArduinoJson/Core/JsonDocument.hpp β€” Core data structure representing a JSON document in memory; understanding its allocation and traversal strategy is essential for performance optimization.
  • src/ArduinoJson/Deserialization/deserialize.hpp β€” Main deserialization entry point that converts JSON text to internal document representation; critical for parsing logic flow.
  • src/ArduinoJson/Serialization/serialize.hpp β€” Main serialization entry point that converts internal document representation back to JSON text; essential for output generation.
  • src/ArduinoJson/Memory/MemoryPool.hpp β€” Memory management abstraction that handles allocation and deallocation; understanding this is vital for embedded resource constraints.
  • src/ArduinoJson/Variant/Variant.hpp β€” Type-agnostic value wrapper supporting JSON primitives and composite types; fundamental to the library's type system.
  • CMakeLists.txt β€” Build configuration that defines compilation flags, includes, and platform-specific settings across compilers and architectures.

πŸ› οΈHow to make changes

Add support for a new input source type

  1. Create a new Reader class implementing the streaming input interface in src/ArduinoJson/Deserialization/ (src/ArduinoJson/Deserialization/Reader.hpp)
  2. Add a deserialize() overload that accepts your Reader type in src/ArduinoJson/Deserialization/deserialize.hpp (src/ArduinoJson/Deserialization/deserialize.hpp)
  3. Test the new reader against the test suite in extras/tests/ to ensure correct parsing behavior (extras/tests)
  4. Export the new type in the main header if it's a public API (ArduinoJson.h)

Add a custom memory allocator strategy

  1. Create a new Allocator class in src/ArduinoJson/Memory/ implementing alloc/dealloc/capacity interfaces (src/ArduinoJson/Memory/MemoryPool.hpp)
  2. Modify JsonDocument template to accept your allocator as a template parameter (src/ArduinoJson/Core/JsonDocument.hpp)
  3. Add compilation tests in extras/conf_test/ to validate the allocator on target platforms (extras/conf_test/avr.cpp)

Add a new serialization output format (e.g., MessagePack)

  1. Create a format-specific serializer in src/ArduinoJson/Serialization/ (e.g., MsgPackSerializer.hpp) (src/ArduinoJson/Serialization/JsonSerializer.hpp)
  2. Implement format encoding logic while reusing the traversal logic from JsonSerializer (src/ArduinoJson/Serialization/serialize.hpp)
  3. Add an example sketch in examples/ demonstrating the new format (examples/MsgPackParser/MsgPackParser.ino)

Optimize memory usage for a specific platform

  1. Add platform-specific configuration flags in src/ArduinoJson/Configuration.hpp (src/ArduinoJson/Configuration.hpp)
  2. Create conditional compilation tests in extras/conf_test/ for your target (extras/conf_test/x64.cpp)
  3. Add compiler-specific optimization flags in CMakeLists.txt or component.mk (CMakeLists.txt)

πŸ”§Why these technologies

  • Header-only / template-heavy C++ β€” Enables compile-time optimization, zero-cost abstractions, and tight control over memory layout critical for embedded/Arduino targets with limited RAM.
  • Fixed-size memory pool (arena allocator) β€” Eliminates fragmentation and heap pressure on embedded systems; predictable allocation timing for real-time constraints.
  • Variant/polymorphic value type β€” Avoids complex inheritance hierarchies; stores heterogeneous JSON types (null, bool, number, string, array, object) in a memory-efficient union.
  • Streaming parser (vs. DOM-only) β€” Allows parsing from limited I/O sources (serial UART, network sockets) without loading entire JSON into memory first.

βš–οΈTrade-offs already made

  • Document capacity set at compile/initialization time (not auto-growing)

    • Why: Embedded systems cannot tolerate unbounded heap growth; users must right-size buffers.
    • Consequence: Safe resource usage but requires upfront capacity planning; overflow attempts fail gracefully without dynamic reallocation.
  • No exceptions; returns error codes or nullopt values

    • Why: Arduino/embedded C++ often disables exceptions for code size and overhead; matches idioms of bare-metal systems.
    • Consequence: Callers must check return values; less automatic error propagation but lower runtime cost.
  • Variant stores all 6 JSON types in a single union; no inheritance hierarchy

    • Why: Minimizes memory overhead per value (typically 8–16 bytes vs. 24+ with vtable/heap allocation).
    • Consequence: No virtual dispatch; type checking and conversions done via tag field; slightly less OOP but better performance and predictability.
  • Immutable APIs for const access; mutable APIs for modification

    • Why: Allows optimizations and safer reference semantics; mirrors const-correctness idioms.
    • Consequence: Two parallel class hierarchies (JsonVariantConst vs. JsonVariant); more boilerplate but stronger compile-time guarantees.

🚫Non-goals (don't propose these)

  • Does not provide schema validation or JSON Schema support
  • Not a streaming parser that emits events (only supports object/array deserialization into a document tree)
  • Does not handle circular references or custom serialization of user-defined types (only JSON primitives)
  • Not a validation framework; does not perform deep security audits (e.g., redaction of sensitive fields)
  • Not suitable for gigabyte-scale JSON processing; designed for typical embedded configs and API payloads (<1 MB)

πŸͺ€Traps & gotchas

No external runtime dependencies, but template-heavy C++ means long compile times and large generated binaries on first use. Embedded systems require careful memory allocator configuration via custom allocator supportβ€”default may fail on boards with <2KB RAM. Clang/GCC version mismatches can silently pass on one compiler but fail on Arduino's typical GCC 5.4; the .devcontainer matrix is essential for validation. CMake build system is modern but Makefile provides simpler path for quick testing.

πŸ—οΈArchitecture

πŸ’‘Concepts to learn

  • Header-only library design β€” Eliminates linker/ABI compatibility issues on embedded systems with non-standard toolchains; critical for Arduino portability across 20+ compiler versions
  • JSON deserialization (streaming vs DOM) β€” ArduinoJson uses a full DOM model; understanding when to use streaming (SAX-style) vs DOM parsing informs efficient design for memory-constrained boards
  • String deduplication β€” ArduinoJson deduplicates repeated JSON keys/values (mentioned in README v6.16.0); critical optimization reducing RAM by 10% on typical IoT payloads
  • Custom memory allocators β€” ArduinoJson supports pluggable allocators for external FRAM/EEPROM on boards with <2KB RAM; understanding allocator interface is essential for real-world deployment
  • MessagePack binary serialization β€” ArduinoJson supports both JSON and MessagePack formats; MessagePack is more compact (50-60% smaller) for bandwidth-constrained IoT communication
  • UTF-16 to UTF-8 transcoding β€” Optional Unicode escape sequence decoding handles JSON from web APIs; understanding UTF-8 vs UTF-16 encoding is necessary for international IoT applications
  • Template metaprogramming β€” ArduinoJson uses C++ templates for type-safe JSON access without runtime overhead; common pattern in modern embedded C++ libraries requiring zero-cost abstractions
  • nlohmann/json β€” Modern C++ JSON library for desktop/server; shows alternative template-based design for non-embedded contexts
  • Arduino/Arduino_JSON β€” Official Arduino JSON library; ArduinoJson's direct competitor, explicitly benchmarked in README as 2x smaller and 10% faster
  • arduino/ArduinoCore-avr β€” Arduino core libraries and build system; ArduinoJson integrates into this ecosystem as a standard library dependency
  • msgpack/msgpack-c β€” Reference MessagePack implementation; ArduinoJson adds MessagePack serialization/deserialization alongside JSON
  • facebook/zstd β€” Compression library often used alongside JSON serialization for IoT; demonstrates complementary embedded optimization approach

πŸͺ„PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add comprehensive unit tests for ArduinoJson.h header and core serialization edge cases

The repo has extensive CI/CD setup (.github/workflows/ci.yml, appveyor.yml) and multiple compiler configurations (.devcontainer with gcc4.8-12, clang5-17) but the test coverage appears incomplete. Key edge cases in JSON serialization (null bytes in strings, deeply nested objects, integer overflow handling, UTF-8 validation) lack dedicated test suites. This would improve fuzzing effectiveness (oss-fuzz integration exists) and catch regressions across the 15+ compiler versions being tested.

  • [ ] Create test/unit_tests/serialization_edge_cases.cpp for null byte handling, overflow, UTF-8 validation
  • [ ] Create test/unit_tests/nesting_limits.cpp for deeply nested object/array stress tests
  • [ ] Create test/unit_tests/memory_constraints.cpp for embedded systems with limited RAM
  • [ ] Add test execution to existing .github/workflows/ci.yml for these new test suites
  • [ ] Ensure tests run across devcontainer configurations (gcc4.8, gcc12, clang5, clang17) via CMakeLists.txt

Add GitHub Action workflow to test against Arduino IDE and PlatformIO ecosystem

The repo targets Arduino/embedded systems (evidenced by examples/JsonConfigFile/JsonConfigFile.ino, .mbedignore, component.mk) but current CI (.github/workflows/ci.yml, appveyor.yml) likely tests via pure C++ compilation. Missing integration tests with Arduino IDE or PlatformIO would catch breakage in the primary use case. This is critical since the library is distributed via Arduino Library Manager.

  • [ ] Create .github/workflows/arduino-compatibility.yml for Arduino IDE CLI testing
  • [ ] Add test for examples/JsonConfigFile/JsonConfigFile.ino compilation against multiple Arduino board types (esp32, stm32, avr)
  • [ ] Create .github/workflows/platformio.yml for PlatformIO testing across common platforms
  • [ ] Test library.properties compatibility and Arduino Library Manager installation
  • [ ] Document results in README.md with Arduino IDE/PlatformIO badge

Document specific compiler flags and configuration options in a CONFIGURATION.md guide

The presence of extensive .devcontainer configurations (clang5-17, gcc4.8-12) and .clang-format suggests careful control over code style and compiler behavior, but there's no explicit configuration documentation. CONTRIBUTING.md exists but lacks specifics on: how to add new compiler versions, which flags are non-negotiable, embedded platform-specific configurations, and how the CMakeLists.txt handles different target environments. This reduces friction for contributors working with the 15+ compiler variants.

  • [ ] Create CONFIGURATION.md documenting all compiler flags in .clang-format and CMakeLists.txt
  • [ ] Document how each .devcontainer compiler version is selected and why (historical support, ESp32, ARM embedded, etc.)
  • [ ] Add section: 'How to Add a New Compiler Version' with devcontainer template
  • [ ] Document embedded platform-specific defines and how .mbedignore and component.mk interact
  • [ ] Cross-reference from CONTRIBUTING.md to this new guide

🌿Good first issues

  • Add comprehensive benchmark suite for deserialization speed across message sizes (100B–10KB JSON) and compiler versions, comparing against Arduino_JSON baseline mentioned in README
  • Expand test coverage for MessagePack edge cases (nested arrays >255 elements, float32 vs float64 precision) visible only when fuzz testing with OSS-Fuzz input corpus
  • Document allocator interface with concrete examples for external FRAM/EEPROM usage on memory-constrained boards (e.g., Arduino MKR Zero with 32KB RAM)

⭐Top contributors

Click to expand

πŸ“Recent commits

Click to expand
  • d4e745a β€” Rename make_float() to multiplyByPowerOfTen() (bblanchon)
  • 5ccf645 β€” Fix buffer overrun in make_float() (bblanchon)
  • ab8c9be β€” Fuzzing: tidy CMakeLists.txt (bblanchon)
  • 029b3c5 β€” Add pgm_array<T, N> as a bound-safe alternative to pgm_ptr<T> (bblanchon)
  • a9bb1a1 β€” Add a fuzzer for parseNumber() (bblanchon)
  • 34888e5 β€” CI: update macOS runner (bblanchon)
  • aa7fbd6 β€” README: remove the "most popular" claim (bblanchon)
  • 21144d5 β€” Don't rely on array size to get the length of string literals (bblanchon)
  • 5f96515 β€” Particle: update installation method (bblanchon)
  • bec657e β€” Return bool from all built-in toJson converters (bblanchon)

πŸ”’Security observations

ArduinoJson demonstrates good security practices overall. The project uses CI/CD pipelines with multiple compiler versions, maintains code coverage monitoring, and has OSS-Fuzz integration for automated security testing. No critical vulnerabilities were identified in the static analysis of the file structure. Minor improvements include pinning container image versions and establishing a formal security disclosure policy. The codebase is a C++ JSON library with inherent risks related to parsing untrusted input, but these are being mitigated through continuous fuzzing and comprehensive testing across multiple compiler versions.

  • Low Β· Multiple Development Container Images Without Pinned Versions β€” .devcontainer/clang13/Dockerfile, .devcontainer/clang14/Dockerfile, .devcontainer/clang15/Dockerfile, .devcontainer/clang16/Dockerfile, .devcontainer/clang17/Dockerfile, .devcontainer/gcc12/Dockerfile. The .devcontainer configurations use compiler images (gcc, clang) without explicit version pinning in some Dockerfiles. This could lead to unexpected behavior changes when base images are updated, potentially introducing subtle bugs or security issues in the development environment. Fix: Pin specific image versions in Dockerfiles (e.g., 'FROM gcc:12.2.0-bullseye' instead of 'FROM gcc:12-bullseye') to ensure reproducible builds and prevent unexpected changes from base image updates.
  • Low Β· Fuzzing Infrastructure Coverage β€” Project-wide JSON parsing logic. While the project has OSS-Fuzz integration (indicated by the fuzzing badge in README), JSON parsing is a high-risk attack surface area. The codebase handles untrusted input from JSON parsing, which is a common target for fuzzing and security vulnerabilities. Fix: Ensure comprehensive fuzzing coverage for all JSON parsing code paths, particularly edge cases like deeply nested objects, extremely large numbers, and malformed UTF-8 sequences. Continue monitoring OSS-Fuzz reports.
  • Low Β· No SECURITY.md Policy File β€” Repository root. While SUPPORT.md exists, there is no dedicated SECURITY.md file to document security vulnerability reporting procedures. This may make it difficult for security researchers to responsibly disclose vulnerabilities. Fix: Create a SECURITY.md file following GitHub's security advisory guidelines (https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing-information-about-vulnerabilities). Include instructions for responsible disclosure and contact information.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals β€” see the live page for receipts. Re-run on a new commit to refresh.

Healthy signals Β· bblanchon/ArduinoJson β€” RepoPilot