History

Jazz tracks every change to your data automatically. See who changed what, when they did it, and even look at your data from any point in the past.

See the version history example for reference.

Let's use the following schema to see how we can use the edit history.

export const Task = co.map({
  title: z.string(),
  status: z.literal(["todo", "in-progress", "completed"]),
});
export type Task = co.loaded<typeof Task>;

The $jazz.getEdits() method

Every CoValue has a $jazz.getEdits() method that contains the complete history for each field. Here's how to get the edit history for task.status:

task.$jazz.getEdits().status;
// Returns the latest edit

task.$jazz.getEdits().status?.all;
// Returns array of all edits in chronological order

// Check if edits exist
const statusEdits = task.$jazz.getEdits().status;
if (statusEdits && statusEdits.by?.profile.$isLoaded) {
  const name = statusEdits.by.profile.name;
  console.log(`Last changed by ${name}`);
}

Edit Structure

Each edit contains:

const edit = task.$jazz.getEdits().status;

// The edit object contains:
edit?.value; // The new value: "in-progress"
edit?.by; // Account that made the change
edit?.madeAt; // Date when the change occurred

Accessing History

Latest Edit

Get the most recent change to a field:

// Direct access to latest edit
const latest = task.$jazz.getEdits().title;
if (latest) {
  console.log(`Title is now "${latest.value}"`);
}

All Edits

Get the complete history for a field:

// Get all edits (chronologically)
const allStatusEdits = task.$jazz.getEdits().status?.all || [];

allStatusEdits.forEach((edit, index) => {
  console.log(`Edit ${index}: ${edit.value} at ${edit.madeAt.toISOString()}`);
});
// Edit 0: todo at 2025-05-22T13:00:00.000Z
// Edit 1: in-progress at 2025-05-22T14:00:00.000Z
// Edit 2: completed at 2025-05-22T15:30:00.000Z

Initial Values

The first edit contains the initial value:

const allEdits = task.$jazz.getEdits().status?.all || [];
const initialValue = allEdits[0]?.value;
console.log(`Started as: ${initialValue}`);
// Started as: todo

Created Date and Last Updated Date

To show created date and last updated date, use the $jazz.createdAt and $jazz.lastUpdatedAt getters.

console.log(new Date(task.$jazz.createdAt));
console.log(new Date(task.$jazz.lastUpdatedAt));

Requirements

  • CoValues must be loaded to access history (see Subscription & Loading)
  • History is only available for fields defined in your schema
  • Edit arrays are ordered chronologically (oldest to newest)

Common Patterns

For practical implementations using history, see History Patterns:

  • Building audit logs
  • Creating activity feeds
  • Implementing undo/redo
  • Showing change indicators
  • Querying historical data