[API reference](https://evolu.dev/docs/api-reference) › [@evolu/common](https://evolu.dev/docs/api-reference/common) › [local‑first/Schema](https://evolu.dev/docs/api-reference/common/local-first/Schema) › Mutation

```ts
type Mutation<S, Kind> = <TableName>(
  table: TableName,
  values: MutationValues<S[TableName], Kind>,
  options?: MutationOptions,
) => {
  id: InferOutput<S[TableName]["id"]>;
};
```

Defined in: [packages/common/src/local-first/Schema.ts:194](https://github.com/evoluhq/evolu/blob/e7144e2bbe9069362b62dec1b64a8aa922b8f1b0/packages/common/src/local-first/Schema.ts#L194)

Mutation function type. Accepts already-validated values — validation is the
caller's responsibility using any Standard Schema library (Evolu Type, Zod,
Valibot, ArkType, etc.).

Evolu does not use SQL for mutations to ensure data can be deterministically
merged without conflicts. Explicit mutations also allow Evolu to
automatically update [SystemColumns](https://evolu.dev/docs/api-reference/common/local-first/Schema/variables/SystemColumns-1) and encourage developers to
consider the number of changes produced, unlike SQL where a single query can
inadvertently generate a large volume of CRDT messages. Each mutation
produces exactly one [CrdtMessage](https://evolu.dev/docs/api-reference/common/local-first/Storage/interfaces/CrdtMessage) containing all provided columns.

Mutations never fail — values are already validated by the caller, and
changes are stored locally in SQLite.

- **insert**: all non-nullable columns required, nullable columns optional,
  `id` omitted (auto-generated)
- **update**: only `id` required, everything else optional
- **upsert**: like insert but `id` required too