Introduction

If you've ever worked on an SDK that depends on a binary protocol, you know the pain of finding the right library to handle serialization. CBOR (Concise Binary Object Representation) is one of those protocols — compact, efficient, and widely used in IoT and database systems. When I started contributing to the SurrealDB PHP SDK, I quickly found myself deep in the weeds of CBOR encoding and decoding. What I didn't expect was that the available PHP libraries would push me to build my own: cbor-php.

The SurrealDB PHP SDK journey

SurrealDB communicates over a binary protocol that relies heavily on CBOR. When building out the PHP SDK, I needed a solid CBOR implementation that could handle SurrealDB's specific data types and encoding patterns. Naturally, I looked at what already existed in the PHP ecosystem.

What I found were libraries that technically worked but were over-engineered to the point of frustration. Simple operations required wiring up deeply nested class hierarchies. Decoding a basic CBOR payload meant dealing with abstraction layers that added no real value for my use case. Configuration was scattered, extension points were confusing, and the developer experience felt like it was designed for a specification committee rather than someone trying to ship a working SDK.

Integrating these libraries into the SurrealDB SDK introduced unnecessary complexity. The codebase became harder to reason about, debugging CBOR-related issues meant diving through layers of indirection, and the overhead simply wasn't justified for what should have been a straightforward encode/decode operation.

Building my own CBOR library

At some point I had to make a decision: keep fighting with libraries that didn't fit my needs, or build something purpose-built. I chose the latter.

The goal with cbor-php was simple — create a CBOR library that is easy to use, easy to extend, and doesn't over-abstract the problem. I wanted to encode and decode CBOR payloads with minimal setup, support custom tagged types for SurrealDB's specific needs, and keep the API surface small enough that anyone picking up the library could understand it in minutes.

Building it from scratch also meant I had full control over how edge cases were handled, how errors surfaced, and how the library evolved alongside the SDK. No more waiting on upstream maintainers to merge a fix or accept a feature that only mattered for my use case. It was the best bet at the time because it removed the bottleneck entirely and gave the SurrealDB PHP SDK a dependency it could actually rely on.

Reflection

Looking back, building cbor-php taught me a few things that go beyond just writing a serialization library.

First, don't be afraid to build what you need. The ecosystem doesn't always have the right tool, and sometimes the fastest path forward is building it yourself — especially when the scope is well-defined.

Second, simplicity is a feature. The existing libraries weren't bad because they were incomplete. They were hard to use because they prioritized flexibility over clarity. Keeping an API simple and focused makes it easier for others to adopt and contribute to.

Third, owning your dependencies matters. When a core part of your project relies on someone else's library, you're at the mercy of their priorities. For critical-path dependencies, having full ownership can save a lot of headaches down the road.

And finally, building low-level tooling deepens your understanding. Working with a binary protocol at the byte level forced me to truly understand CBOR rather than just consuming it through an abstraction. That knowledge carried over into every other part of the SDK work.

If you're ever stuck between wrestling with a dependency and writing your own, sometimes the answer is simpler than you think — just build it.