immerjs / immerjs/immer

[Feature Request] Support for "Splice" patches in arrays for CRDT/Y.js integration (and others)

Open
#1,202 2 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

proposal
Dominant language
JavaScript
Stars
29k
Forks
881
PR merge metrics
No merged PRs in 30d

Description

Currently, when performing array operations like splice(), shift(), or unshift(), Immer generates standard JSON patches (RFC 6902). While spec-compliant, this approach is inefficient for arrays when items are added or removed from the middle.

For example, given [1, 2, 3, 4], calling .splice(1, 1) results in:

  • replace index 1 with 3
  • replace index 2 with 4
  • remove index 3

The Problem
This "shifting" behavior is problematic for CRDTs (like Y.js) or observation-based libraries (like MobX).

Performance: Large arrays trigger a cascade of patches for a single deletion.

Convergence: In Y.js, "replacing" an element is different from "shifting" it. If Immer reports that every element after the splice point has been replaced, the CRDT loses the identity of those objects, breaking the ability to merge concurrent changes effectively.

Proposed Solution

I propose an optional configuration (e.g., arraySplice: true) that generates a non-standard splice operation for array mutations. This would group push, pop, shift, unshift, and splice into a single descriptive patch.

Example Proposed Patch Format:

{
  "op": "splice",
  "path": "/arr",
  "index": 1,
  "deleteCount": 1,
  "items": [...]
}

Use Case

Y.js / Automerge integration: Directly mapping a splice patch to yArray.delete(index, count) and yArray.insert(index, items).

In MobX / other libs it is just calling a splice operation instead.

Performance Optimization: Reducing the payload size when syncing state across WebSockets.

Identity Preservation: Ensuring that elements not being deleted maintain their reference/identity in the eyes of the consumer.

Additional Context

Libraries like mobx use this observation pattern successfully. While I understand Immer aims for JSON Patch compatibility, providing an opt-in for "Rich Patches" or "Splice Patches" would make it the go-to library for distributed state management.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by evaluating Immer's current array patch generation for splice, shift, and unshift against the proposed arraySplice option and patch format. Compare the design with the Y.js, Automerge, and MobX use cases. Done means an agreed opt-in splice representation that preserves default JSON Patch behavior and covers the listed array operations.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript
Domain
developer-experience, distributed-systems
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.