# Note-cpp — a type-safe C++ library for the Notecard (community project)

**URL:** <https://discuss.blues.com/t/note-cpp-a-type-safe-c-library-for-the-notecard-community-project/3579>\
**Category:** Notecard API\
**Created:** [July 8, 2026, 6:10pm UTC](https://discuss.blues.com/t/note-cpp-a-type-safe-c-library-for-the-notecard-community-project/3579 "2026-07-08T18:10:31Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![mdma](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.blues.com/mdma/32/1836_2.png) [@mdma](https://discuss.blues.com/u/mdma)\
**Post date:** [July 8, 2026, 6:10pm UTC](https://discuss.blues.com/t/note-cpp-a-type-safe-c-library-for-the-notecard-community-project/3579/1 "2026-07-08T18:10:31Z")

</div>

Hi all 👋

I’ve been building **note-cpp** , a header-only C++ library for the Blues Notecard, and I’d love to share it with the community and get your feedback.

The goal was a Notecard API that feels natural in modern C++ — typed requests and responses, no macros-everywhere, and the same code from an ATmega328P all the way up to an ESP32 or a desktop host.

A quick taste:

```cpp
#include <note.hpp>

Notecard nc;
nc.begin(Serial1, 9600); // or nc.begin(Wire) for I2C

nc.hub.set()
    .product("com.example.app")
    .mode("periodic")
    .execute();

auto rsp = nc.card.version().execute();
if (rsp) {
    Serial.println(rsp.version); // typed fields
} else {
    Serial.println(rsp.error());
}

```

**A few things I think make it nice to use:**

- 🧩 **Fully typed API** for all 74 Notecard requests — fluent (`nc.hub.set().product(...)`) or plain assignment, with typed response fields instead of digging through JSON.
- 🪶 **Header-only, zero dependencies** , C++17/20/23 (later standards unlock more compile-time checks).
- 📉 **Scales from tiny to large** — the _same_ API runs on an Arduino Uno (ATmega328P) all the way up through ESP32, Cortex-M, and Linux/macOS. On the Uno the fully-typed build lands around 80% of flash with **zero heap** — roughly flash-parity with hand-written note-c, and lighter on RAM — and if you need headroom, leaner call styles drop the same app to ~36% of flash. You dial memory and flash use without changing your call sites.
- 🛡 **Catches mistakes at compile time** — on C++20 it validates string constants like `mode`/`triggers`, and can constrain the API to your hardware variant + firmware version, and gives each request intent its own type (setting a field that doesn’t apply is a compile error).
- 🔧 **Your memory, your rules** — arena (zero heap), `HeapResetPool`, plain `malloc`, `std::pmr`, or a custom allocator; the typed API is identical across all of them.
- 🔌 **Serial + I2C built in** with CRC auto-detection, retries, segmentation, and binary transfer (`card.binary.put`/`get`) — plus an optional compact JSONB wire format for constrained targets.
- ✅ **Well tested** — the same test cases run on host compilers _and_ on real Notecard hardware over serial/I2C, with high coverage.

Your own structs work as note bodies for send, receive, _and_ `note.template` registration:

```cpp
struct Readings {
    float temperature;
    int16_t humidity;
    NOTE_FIELDS(temperature, humidity) // optional on C++20+
};

nc.note.add().file("sensors.qo").body(Readings{22.5f, 60}).execute();

```

**A note on scope:** this is an independent community project — not affiliated with or supported by Blues, and “Notecard” is their trademark. It assumes you’re already comfortable with the Notecard and its API.

Repo, docs, and examples: [GitHub - m-mcgowan/note-cpp: Type-safe C++ API for the Blues Notecard. Header-only, zero dependencies. C++17/20/23. · GitHub](https://github.com/m-mcgowan/note-cpp)

I’d genuinely welcome feedback, bug reports, or “I tried it on X board” reports. Thanks for taking a look! 🙏

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex020/uploads/blues/original/1X/5d46f31b01469dfa80dbe1f6838289a3cdbae5e9.png) [@system](https://discuss.blues.com/u/system)\
**Post date:** [July 23, 2026, 6:33pm UTC](https://discuss.blues.com/t/note-cpp-a-type-safe-c-library-for-the-notecard-community-project/3579/2 "2026-07-23T18:33:34Z")

</div>



---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex020/uploads/blues/original/1X/5d46f31b01469dfa80dbe1f6838289a3cdbae5e9.png) [@system](https://discuss.blues.com/u/system)\
**Post date:** [July 23, 2026, 6:36pm UTC](https://discuss.blues.com/t/note-cpp-a-type-safe-c-library-for-the-notecard-community-project/3579/3 "2026-07-23T18:36:48Z")

</div>



---

<div class="post-metadata">

**Author:** ![mdma](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.blues.com/mdma/32/1836_2.png) [@mdma](https://discuss.blues.com/u/mdma)\
**Post date:** [July 26, 2026, 8:00am UTC](https://discuss.blues.com/t/note-cpp-a-type-safe-c-library-for-the-notecard-community-project/3579/4 "2026-07-26T08:00:58Z")

</div>

**Quick update since the first post** — a couple of things worth sharing.

**Installing it is easier now.** `note-cpp` is in the **Arduino Library Manager** (search “note-cpp”) and the **PlatformIO Registry** :

```ini
; platformio.ini
lib_deps = m-mcgowan/note-cpp

```

Also, and this is the part I most wanted to call out, `note-cpp` can run **alongside your existing `note-c` / `note-arduino` code on the same Notecard connection** , so an existing solution can be migrated incrementally — one request at a time, with no all-or-nothing rewrite.

It works via a small bridge transport: `note-c` keeps owning the serial/I²C bus exactly as it does today, and `note-cpp`’s typed API rides on top of it by delegating each request to `NoteRequestResponseJSON()`. Your existing `J*` / `NoteRequest` code keeps working untouched while new code uses the typed API on the same wire:

```cpp
// Existing note-c code — unchanged, still owns the bus:
J *req = NoteNewRequest("hub.set");
JAddStringToObject(req, "product", "com.example.app");
NoteRequest(req);

// New code, typed note-cpp API, same connection
// (nc = note-cpp's typed handle, riding the bridge):
nc.note.add().file("sensors.qo").body(reading).execute();

```

A typical migration flow goes like this:

1. **Add `note-cpp` in behind the bridge** — keep all your existing setup and link both libraries. Nothing changes on the wire.
2. **Port request sites one at a time** to the note-cpp typed API. Half-migrated is fine; both styles share the connection.
3. **Cut over the transport** when you’re ready — swap the bridge for a non-bridged `note-cpp` transport and drop the `note-c` dependency. This step is optional; you can stay in bridge mode as long as you like, but once you do switch, you get the benefits of note-cpp’s streaming and a reduced memory footprint.

Full write-up, including the bridge implementation and the cut-over steps:

- From note-arduino → [Running note-cpp alongside note-c](https://github.com/m-mcgowan/note-cpp/blob/main/docs/platforms/arduino/migration-from-note-arduino.md#running-note-cpp-alongside-note-c)
- From note-c, any platform → [Bridge mode](https://github.com/m-mcgowan/note-cpp/blob/main/docs/platforms/host/migration-from-note-c.md#bridge-mode-incremental-migration)

Still a community project, not affiliated with Blues — the goal is to complement `note-c` / `note-arduino`, not replace them. As always, feedback and issues are very welcome.
