npm-packages/docs/docs/functions/mutation-functions.mdx
import Example from "!!raw-loader!@site/../private-demos/snippets/convex/mutationsExample.ts"; import Constructor from "!!raw-loader!@site/../private-demos/snippets/convex/mutationsConstructor.ts"; import ArgsWithoutValidationTS from "!!raw-loader!@site/../private-demos/snippets/convex/mutationsArgsWithoutValidation.ts"; import ArgsWithoutValidationJS from "!!raw-loader!@site/../private-demos/snippets/convex/mutationsArgsWithoutValidationJS.js"; import ArgsWithValidation from "!!raw-loader!@site/../private-demos/snippets/convex/mutationsArgsWithValidation.ts"; import Context from "!!raw-loader!@site/../private-demos/snippets/convex/mutationsContext.ts"; import ContextDB from "!!raw-loader!@site/../private-demos/snippets/convex/mutationsContextDB.ts"; import Helper from "!!raw-loader!@site/../private-demos/snippets/convex/mutationsHelper.ts"; import HelperJS from "!!raw-loader!@site/../private-demos/snippets/convex/mutationsHelperJS.js"; import NPM from "!!raw-loader!@site/../private-demos/snippets/convex/mutationsNPM.ts"; import Call from "!!raw-loader!@site/../private-demos/snippets/src/mutationsCall.tsx";
Mutations insert, update and remove data from the database, check authentication or perform other business logic, and optionally return a response to the client application.
This is an example mutation, taking in named arguments, writing data to the database and returning a result:
<TSAndJSSnippet sourceTS={Example} sourceJS={Example} title="convex/myFunctions.ts" />
Read on to understand how to build mutations yourself.
Mutations follow the same naming rules as queries, see Query names.
Queries and mutations can be defined in the same file when using named exports.
mutation constructorTo declare a mutation in Convex use the mutation constructor function. Pass it
an object with a handler function, which performs the mutation:
<TSAndJSSnippet sourceTS={Constructor} sourceJS={Constructor} title="convex/myFunctions.ts" />
Unlike a query, a mutation can but does not have to return a value.
Just like queries, mutations accept named arguments, and the argument values are
accessible as fields of the second parameter of the handler function:
<TSAndJSSnippet sourceTS={ArgsWithoutValidationTS} sourceJS={ArgsWithoutValidationJS} title="convex/myFunctions.ts" />
Arguments and responses are automatically serialized and deserialized, and you can pass and return most value-like JavaScript data to and from your mutation.
To both declare the types of arguments and to validate them, add an args
object using v validators:
<TSAndJSSnippet sourceTS={ArgsWithValidation} sourceJS={ArgsWithValidation} title="convex/myFunctions.ts" />
See argument validation for the full list of supported types and validators.
The first parameter to the handler function is reserved for the mutation context.
Queries can return values of any supported Convex type which will be automatically serialized and deserialized.
Mutations can also return undefined, which is not a valid Convex value. When a
mutation returns undefined it is translated to null on the client.
The mutation constructor enables writing data to the database, and other
Convex features by passing a MutationCtx
object to the handler function as the first parameter:
<TSAndJSSnippet sourceTS={Context} sourceJS={Context} title="convex/myFunctions.ts" />
Which part of the mutation context is used depends on what your mutation needs to do:
To read from and write to the database use the db field. Note that we make
the handler function an async function so we can await the promise
returned by db.insert():
<TSAndJSSnippet sourceTS={ContextDB} sourceJS={ContextDB} title="convex/myFunctions.ts" />
Read on about Writing Data.
To generate upload URLs for storing files use the storage field. Read on
about File Storage.
To check user authentication use the auth field. Read on about
Authentication.
To schedule functions to run in the future, use the scheduler field. Read on
about Scheduled Functions.
<> When you want to split up the code in your mutation or reuse logic across multiple Convex functions you can define and call helper <LanguageSelector verbose /> functions: </>
<TSAndJSSnippet sourceTS={Helper} sourceJS={HelperJS} title="convex/myFunctions.ts" />
Mutations can call helpers that take a QueryCtx as argument, since the mutation context can do everything query context can.
You can export helpers to use them across multiple files. They will not be
callable from outside of your Convex functions.
See Type annotating server side helpers for more guidance on TypeScript types.
Mutations can import NPM packages installed in node_modules. Not all NPM
packages are supported, see
Runtimes for more details.
npm install @faker-js/faker
To call a mutation from React use the
useMutation hook along with the generated
api object.
See the React client documentation for all the ways queries can be called.
When mutations are called from the React or Rust clients, they are executed one at a time in a single, ordered queue. You don't have to worry about mutations editing the database in a different order than they were triggered.
Mutations run transactionally. This means that:
For this to work, similarly to queries, mutations must be deterministic, and cannot call third party APIs. To call third party APIs, use actions.
Mutations have a limit to the amount of data they can read and write at once to guarantee good performance. Learn more in Read/write limit errors.
For information on other limits, see Limits.