Documentation Index Fetch the complete documentation index at: https://mintlify.com/TanStack/query/llms.txt
Use this file to discover all available pages before exploring further.
Perform mutations and side effects with the createMutation function. It provides methods to trigger mutations and tracks their state reactively in Svelte 5.
Signature
function createMutation < TData , TError , TVariables , TContext >(
options : Accessor < CreateMutationOptions < TData , TError , TVariables , TContext >>,
queryClient ?: Accessor < QueryClient >,
) : CreateMutationResult < TData , TError , TVariables , TContext >
Parameters
options
Accessor<CreateMutationOptions<TData, TError, TVariables, TContext>>
required
A function (accessor) returning mutation configuration options. mutationFn
(variables: TVariables) => Promise<TData>
required
The function that performs the mutation.
onMutate
(variables: TVariables) => Promise<TContext> | TContext
Called before mutation executes. Useful for optimistic updates. Return context value.
onSuccess
(data: TData, variables: TVariables, context: TContext) => void
Called when mutation succeeds.
onError
(error: TError, variables: TVariables, context: TContext | undefined) => void
Called when mutation fails.
onSettled
(data: TData | undefined, error: TError | null, variables: TVariables, context: TContext | undefined) => void
Called when mutation completes (success or error).
Number of retry attempts or boolean to enable/disable retries.
retryDelay
number | ((attemptIndex: number) => number)
Delay between retry attempts.
Throw errors instead of setting error state.
Accessor returning a custom QueryClient instance. If not provided, uses the client from context.
Returns
CreateMutationResult<TData, TError, TVariables, TContext>
Reactive mutation state and methods. mutate
(variables: TVariables, options?: MutateOptions) => void
Trigger the mutation. Fire-and-forget style (doesn’t return a promise).
mutateAsync
(variables: TVariables, options?: MutateOptions) => Promise<TData>
Trigger the mutation and return a promise.
The mutation result data.
The error object if the mutation failed.
true when the mutation is currently executing.
true when the mutation has succeeded.
true when the mutation has failed.
true when the mutation is idle (not executing).
status
'idle' | 'pending' | 'error' | 'success'
The current status of the mutation.
The variables passed to the mutation.
Reset the mutation state to initial values.
Type Parameters
TData - Type of data returned by the mutation
TError - Type of error (defaults to DefaultError)
TVariables - Type of variables passed to the mutation (defaults to void)
TContext - Type of context returned by onMutate (defaults to unknown)
Examples
Basic Usage (Svelte 5 Runes)
< script lang = "ts" >
import { createMutation , useQueryClient } from '@tanstack/svelte-query'
const queryClient = useQueryClient ()
const mutation = createMutation (() => ({
mutationFn : async ( newTodo ) => {
const res = await fetch ( '/api/todos' , {
method: 'POST' ,
headers: { 'Content-Type' : 'application/json' },
body: JSON . stringify ( newTodo ),
})
return res . json ()
},
onSuccess : () => {
queryClient . invalidateQueries ({ queryKey: [ 'todos' ] })
},
}))
function handleCreate () {
mutation . mutate ({ title: 'New Todo' , completed: false })
}
</ script >
< button onclick = { handleCreate } disabled = { mutation . isPending } >
{ mutation . isPending ? 'Adding...' : 'Add Todo' }
</ button >
{# if mutation . isError }
< div > Error: { mutation . error ?. message } </ div >
{/ if }
With TypeScript
< script lang = "ts" >
import { createMutation } from '@tanstack/svelte-query'
interface Todo {
id : number
title : string
completed : boolean
}
interface CreateTodoVariables {
title : string
completed : boolean
}
const mutation = createMutation (() => ({
mutationFn : async ( variables : CreateTodoVariables ) : Promise < Todo > => {
const res = await fetch ( '/api/todos' , {
method: 'POST' ,
body: JSON . stringify ( variables ),
})
return res . json ()
},
}))
function handleCreate () {
// Type-safe mutation call
mutation . mutate ({ title: 'Learn Svelte Query' , completed: false })
}
</ script >
Optimistic Updates
< script lang = "ts" >
import { createMutation , useQueryClient } from '@tanstack/svelte-query'
const queryClient = useQueryClient ()
const mutation = createMutation (() => ({
mutationFn: updateTodo ,
onMutate : async ( updatedTodo ) => {
// Cancel outgoing refetches
await queryClient . cancelQueries ({ queryKey: [ 'todos' ] })
// Snapshot previous value
const previousTodos = queryClient . getQueryData ([ 'todos' ])
// Optimistically update cache
queryClient . setQueryData ([ 'todos' ], ( old ) => {
return old . map ( todo =>
todo . id === updatedTodo . id ? updatedTodo : todo
)
})
// Return context with snapshot
return { previousTodos }
},
onError : ( err , updatedTodo , context ) => {
// Rollback on error
if ( context ?. previousTodos ) {
queryClient . setQueryData ([ 'todos' ], context . previousTodos )
}
},
onSettled : () => {
// Always refetch after error or success
queryClient . invalidateQueries ({ queryKey: [ 'todos' ] })
},
}))
</ script >
Using mutateAsync
< script lang = "ts" >
import { createMutation } from '@tanstack/svelte-query'
const mutation = createMutation (() => ({
mutationFn: createTodo ,
}))
async function handleSubmit () {
try {
const newTodo = await mutation . mutateAsync ({ title: 'New Todo' })
console . log ( 'Created todo:' , newTodo )
// Navigate or show success message
} catch ( error ) {
console . error ( 'Failed to create todo:' , error )
}
}
</ script >
< button onclick = { handleSubmit } > Submit </ button >
Per-Mutation Callbacks
< script lang = "ts" >
import { createMutation } from '@tanstack/svelte-query'
const mutation = createMutation (() => ({
mutationFn: createTodo ,
}))
function handleCreate () {
mutation . mutate (
{ title: 'New Todo' },
{
onSuccess : ( data ) => {
console . log ( 'Created:' , data )
},
onError : ( error ) => {
console . error ( 'Failed:' , error )
},
}
)
}
</ script >
Reset Mutation State
< script lang = "ts" >
import { createMutation } from '@tanstack/svelte-query'
const mutation = createMutation (() => ({
mutationFn: createTodo ,
}))
function handleCreate () {
mutation . reset () // Reset previous state
mutation . mutate ({ title: 'New Todo' })
}
</ script >
< button onclick = { handleCreate } > Create </ button >
{# if mutation . isSuccess }
< div > Successfully created! </ div >
{/ if }
Multiple Mutations
< script lang = "ts" >
import { createMutation , useQueryClient } from '@tanstack/svelte-query'
const queryClient = useQueryClient ()
const createMutation = createMutation (() => ({
mutationFn: createTodo ,
onSuccess : () => {
queryClient . invalidateQueries ({ queryKey: [ 'todos' ] })
},
}))
const deleteMutation = createMutation (() => ({
mutationFn: deleteTodo ,
onSuccess : () => {
queryClient . invalidateQueries ({ queryKey: [ 'todos' ] })
},
}))
</ script >
< button
onclick = { () => createMutation . mutate ({ title: 'New' }) }
disabled = { createMutation . isPending }
>
Create
</ button >
< button
onclick = { () => deleteMutation . mutate ( 1 ) }
disabled = { deleteMutation . isPending }
>
Delete
</ button >
Error Handling with Retry
< script lang = "ts" >
import { createMutation } from '@tanstack/svelte-query'
const mutation = createMutation (() => ({
mutationFn: createTodo ,
retry: 3 ,
retryDelay : ( attemptIndex ) => Math . min ( 1000 * 2 ** attemptIndex , 30000 ),
onError : ( error ) => {
console . error ( 'Mutation failed after retries:' , error )
},
}))
</ script >
Reactive Mutation Options
< script lang = "ts" >
import { createMutation } from '@tanstack/svelte-query'
let shouldRetry = $ state ( true )
const mutation = createMutation (() => ({
mutationFn: createTodo ,
retry: shouldRetry ? 3 : 0 ,
}))
</ script >
< label >
< input type = "checkbox" bind : checked = { shouldRetry } />
Enable retry
</ label >
< script lang = "ts" >
import { createMutation } from '@tanstack/svelte-query'
let title = $ state ( '' )
const mutation = createMutation (() => ({
mutationFn: createTodo ,
onSuccess : () => {
title = '' // Clear form on success
},
}))
function handleSubmit ( e : Event ) {
e . preventDefault ()
mutation . mutate ({ title , completed: false })
}
</ script >
< form onsubmit = { handleSubmit } >
< input
type = "text"
bind : value = { title }
placeholder = "Todo title"
disabled = { mutation . isPending }
/>
< button type = "submit" disabled = { mutation . isPending } >
{ mutation . isPending ? 'Adding...' : 'Add Todo' }
</ button >
</ form >
{# if mutation . isError }
< p class = "error" > { mutation . error ?. message } </ p >
{/ if }
{# if mutation . isSuccess }
< p class = "success" > Todo added successfully! </ p >
{/ if }
Loading States
< script lang = "ts" >
import { createMutation } from '@tanstack/svelte-query'
const mutation = createMutation (() => ({
mutationFn: createTodo ,
}))
</ script >
< button onclick = { () => mutation . mutate ({ title: 'New' }) } >
Create Todo
</ button >
{# if mutation . isPending }
< div > Creating... </ div >
{: else if mutation . isError }
< div > Error: { mutation . error ?. message } </ div >
{: else if mutation . isSuccess }
< div > Todo created successfully! </ div >
{/ if }
Notes
Svelte Query uses Svelte 5’s runes mode. The options parameter must be an accessor (function).
Use mutate for fire-and-forget operations and mutateAsync when you need to await the result or handle errors with try/catch.
Always invalidate or update relevant queries after a successful mutation to keep your UI in sync with the server state.