Skip to main content

createDraft / finishDraft lesson 11: Creating async producers (and why you shouldn’t)

createDraft and finishDraft

createDraft and finishDraft are two low-level functions that are mostly useful for libraries that build abstractions on top of immer. It avoids the need to always create a function in order to work with drafts. Instead, one can create a draft, modify it, and at some time in the future finish the draft, in which case the next immutable state will be produced.

Beyond that, createDraft / finishDraft could be used to express async updates to drafts:

import {createDraft, finishDraft} from "immer"

const user = {
name: "michel",
todos: []

const draft = createDraft(user)
draft.todos = await (await window.fetch("http://host/" +
const loadedUser = finishDraft(draft)

Note: The above is an anti-pattern! First fetch data instead, then draft the user. Otherwise updates to user that happen during the async process, would be "missed" by the draft.

Note: finishDraft takes a patchListener as second argument, which can be used to record the patches, similarly to produce.

Warning: in general, we recommend to use produce instead of the createDraft / finishDraft combo, produce is less error prone in usage, and more clearly separates the concepts of mutability and immutability in your code base.