agentsclimarketplace

Mobile offline sync

Skill SkillMedev/mobile-app-engineering/skills/mobile-offline-sync

Build and ship native and cross-platform mobile apps with Claude.

Install
npx -y skills add SkillMedev/mobile-app-engineering --skill mobile-offline-sync

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Builds local-first mobile storage with an optimistic local store, durable mutation outbox, per-entity conflict-resolution rules, incremental pull, and idempotent background retry. Use when someone says "the app has to work offline", "how do I sync Room or SQLite or Realm with the server", "what happens when two devices edit the same record", or offline edits must reconcile with the server later. Do NOT use for paginating, caching, and refreshing read-heavy server lists - use pagination-and-sync-engineer instead; and do NOT build offline write support for strong-consistency operations like payments or inventory counts - disable those offline.

SKILL.md

7.8 KB, as published. Nobody here has run it

Mobile Offline Sync

Make the local store the source of truth the UI reads and writes, and treat the network as eventual replication. The hard part is never the happy path - it is reconciling divergent edits made while offline. The costly failure is an ad-hoc "retry the request later" queue that double-applies mutations, resurrects deleted rows, and silently destroys one user's edits with another's.

Operating procedure

Step 1: Gather inputs

Collect per feature before designing:

  1. The entities that must work offline, and for each: single-owner or multi-writer? Whole-object edits or field-level edits?
  2. The maximum realistic offline window (a field-service app may need 7-30 days; a consumer app usually hours). This sets tombstone retention.
  3. The local store (Room, SwiftData, SQLite, Realm) and whether the server API can accept client-generated UUIDs and return per-record versions.
  4. Which operations are strong-consistency (payments, inventory decrements, seat booking) - these get disabled offline, not synced.
  5. Expected data volume per user, which decides pull batch sizes.

Label unknowns as guesses and validate them against the server team before building.

Step 2: Make the local store the UI's truth

Write to the local database synchronously and reflect it in the UI immediately (optimistic). Never block the UI on a network round-trip. Tag every row with a sync state - pending, syncing, synced, failed - so the UI can show subtle pending indicators and surface failures.

Step 3: Queue mutations as intents, not raw requests

Record each offline change in a durable outbox table: operation (create/update/delete), entity id, changed fields, client timestamp, the base version the client last saw, and a client-generated UUID. Send the outbox in order, batched (up to about 50 mutations per request keeps payloads small and retries cheap). The server dedupes on the UUID so a retried request never double-applies.

Step 4: Choose a conflict-resolution rule per entity and write it down

There is no universal default. Apply this decision table per entity, top to bottom:

QuestionIf yesIf no
Does the server enforce a business invariant on this entity (state machines, balances, assignments)?Server-authoritative: client proposes, server decides, client rebases local state on the server's answerNext question
Do multiple writers concurrently edit the same record in normal use?Next questionLast-write-wins on server-assigned version or hybrid logical clock - never raw device clocks
Do concurrent edits usually touch different fields?Field-level merge: per-field versions, merge disjoint field sets, LWW per field on true collisionsNext question
Is it collaborative text or a shared set/list needing convergence without a coordinator?CRDT (text CRDT for documents, OR-Set for collections) - accept the metadata and complexity costServer-authoritative with an explicit user-facing conflict prompt

Rules of thumb: server-authoritative is the simplest correct default when the server can decide. LWW is acceptable only for single-owner, whole-object data where losing an overwritten edit is tolerable. CRDTs are the last resort, not the default - they buy convergence at real complexity cost.

Step 5: Pull, detect, reconcile

Pull incrementally with a server cursor or updated_since watermark - never full table scans. Detect a conflict by comparing the base version the client last saw against the server's current version. Apply the entity's resolution rule, write the reconciled result back locally, and clear the pending flag. Keep tombstones for deletes - retained at least as long as the maximum offline window from Step 1 - so a deletion is not resurrected by a stale upsert.

Step 6: Retry as if the network is hostile

Retry with exponential backoff plus jitter: 2s base, doubling, capped at 10 minutes, with plus-or-minus 50 percent jitter; cap at roughly 8 attempts, then park the mutation as failed and surface it to the user. Schedule background sync with WorkManager (Android) or BGTaskScheduler (iOS) under OS constraints - the OS decides when it runs. Make every sync operation idempotent so a process kill mid-flight is safe to repeat.

Worked artifact: conflict-resolution decision for a field-service app

EntityWritersEdit shapeRule chosenWhy
Job status (assigned -> en route -> done)Technician + dispatcherState transitionServer-authoritativeServer enforces the legal state machine; client rebases if its transition was stale
Technician visit notesOne technicianAppend textLWW on server versionSingle owner; concurrent edits effectively impossible
Customer record (phone, address, gate code)Technician + office staffDifferent fieldsField-level mergeOffice edits billing fields while tech edits access notes; merging disjoint fields loses nothing
Shared parts checklist on a jobMultiple techniciansAdd/remove itemsCRDT (OR-Set)Concurrent adds/removes of the same list must converge without losing anyone's items
Invoice payment captureAnyoneMoney movementDisabled offlineStrong consistency; show "reconnect to take payment"

The artifact to keep: this table, one row per synced entity, committed alongside the schema.

Deliverable

Produce an offline-sync design containing: the entity list with a written conflict rule per entity (table above), the outbox schema (operation, entity id, changed fields, base version, client UUID, client timestamp), the pull watermark strategy, the backoff/retry parameters, tombstone retention matched to the offline window, and the list of operations deliberately disabled offline.

Quality bar

  • The UI never waits on the network for a write; every local write is visible instantly with a sync-state tag.
  • Every mutation carries a client-generated UUID and base version; replaying the entire outbox produces the same server state every time.
  • Each synced entity has a documented conflict rule from the decision table, and no rule trusts the device clock for correctness.
  • Deletes leave tombstones retained longer than the maximum offline window; a stale upsert cannot resurrect a deleted row.
  • Killing the app mid-sync and relaunching converges to a consistent state with no duplicates and no lost edits.

Do NOT

  • Do NOT replay raw HTTP requests from a log - that loses ordering and idempotency. Queue intents in an outbox instead.
  • Do NOT decide conflicts by comparing raw device clocks; a skewed clock silently destroys data. Use server-assigned versions or a hybrid logical clock.
  • Do NOT default to CRDTs to avoid choosing - they are for genuine multi-writer convergence and cost metadata and complexity.
  • Do NOT pull full tables on every sync; use a cursor or watermark.
  • Do NOT hard-delete rows without a tombstone.
  • Do NOT fake offline support for strong-consistency operations (payments, inventory counts). Disable the action while offline and tell the user why.
  • Do NOT build full offline sync where the UX does not demand it - it is expensive; for read-heavy list caching and refresh, pagination-and-sync-engineer is the right tool.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.