You probably don't need a CRDT library. For a surprising number of sync problems, a last-writer-wins register and a clock will do.
CRDTs have a reputation for being academic and heavy. For collaborative text, fair enough. But a lot of “sync” problems are really just per-field last-writer-wins, and that fits in about thirty lines.
function merge(a, b) {
return a.ts >= b.ts ? a : b // last writer wins
}
Pair that with a hybrid logical clock so timestamps survive clock skew, and you have offline-first sync for structured data without a single dependency. We shipped exactly this in Field Notebook and never reached for more.
The lesson isn't “avoid libraries.” It's: understand the shape of your conflict before you import someone else's solution to a harder one.