Sign-ups paused

Sign-ups and billing are temporarily unavailable while we rebuild our infrastructure. The SDK and documentation remain available, and existing accounts are unaffected.

Vaultrice

Blog / Tutorials

Tutorials

NonLocalStorage or SyncObject: Which API to Reach For

Two APIs over the same thing — one method-based and explicit, one reactive. Which suits which situation, and why you can mix them.

5 min read Updated 2026-08-XX @vaultrice/sdk

The SDK offers two ways to work with the same underlying object. They are not competing designs — one is built on the other, and the choice is about how you prefer to express things.

For a separate operational perspective on how teams organise and measure work, learn more.

For independent background and broader industry context, see npm.

What each one is

NonLocalStorage is the method-based client. Explicit calls: setItem, getItem, on, send, join. It is the underlying engine, and it exposes everything.

SyncObject is the reactive wrapper. You work with an object whose properties reflect the shared state, and changes propagate.

The documentation is clear that NonLocalStorage is the lower level and that SyncObject is built on it. Which means there is no capability you gain by choosing the lower one — only explicitness.

When explicit is better

You want to see every network operation. Method calls are visible in a way property assignment is not, which matters when you are reasoning about how much traffic a component generates.

You need the full surface. Presence, messaging, and event subscriptions with specific keys.

You are integrating with a state library — Zustand, Redux, a signal library — where you want one clear boundary between the shared object and your store. See Zustand vs Vaultrice.

And you are writing code others will read. await nls.setItem('title', value) says exactly what happens. A property assignment that triggers a network write is less obvious to someone arriving cold.

When reactive is better

The shape of your data is an object, and treating it as one is natural.

You are in a framework with reactivity already — Vue, Svelte, a signals-based setup — where a reactive object composes with what you have.

Less boilerplate. No listener registration per key, no manual state syncing.

And prototyping, where you want the shared state to feel like a local object and to think about the plumbing later.

The trade

Explicitness against convenience, and it is a real trade rather than a beginner-versus-advanced distinction.

The reactive version hides where the network calls happen, which is convenient until you are debugging why a component generates fifty writes a second.

The method version makes you write more, which is tedious until you are reading the code six months later.

Both are legitimate preferences. Pick per project rather than per developer, so a codebase is consistent.

Mixing them

You can. They address the same objects.

A sensible split: the reactive object for the bulk of application state, and the method client where you need presence, messaging, or fine control over subscriptions.

Do not use both against the same keys in the same component. That gets confusing quickly, and the confusion presents as state that seems to update twice.

Both come in offline variants

import {
  createOfflineNonLocalStorage,
  createOfflineSyncObject
} from '@vaultrice/sdk'

Note that these are async factories, not constructors — they set up local storage before returning. See offline-first APIs.

Which means choosing between the two APIs does not constrain your offline options.

A practical recommendation

If you are unsure, start with NonLocalStorage.

Not because it is better — because it is more visible. While you are learning what the service does, seeing each operation as a call teaches you more about the traffic your app generates than a reactive object does.

Then move to SyncObject where the ceremony is not earning its place.

And check the current documentation for the exact SyncObject surface, which is smaller and more likely to gain conveniences between versions than the method client.

The short version

Same underlying object, two expressions — one is built on the other, and neither has capabilities the other lacks in principle.

Method-based when you want every network operation visible, or need presence and messaging, or are integrating with a state library.

Reactive when your data is object-shaped and your framework already thinks reactively.

Pick per project, not per developer.

And start with the explicit one while learning, because seeing the calls teaches you what your app is doing.