Skip to content
Effect Days 2026 Get your ticket

TxRef

Transactional references for coordinating mutable state with Effect transactions. A TxRef stores a current value, but reads and writes inside Effect.tx are recorded in a transaction journal and committed together only when the outermost transaction succeeds.

This is the basic building block behind the other transactional collections in Effect. The module provides effectful and unsafe constructors plus the core operations for reading, setting, updating, and modifying a transactional value while returning a separate result.

7 exports Added in v2.0.0 Source

Combinators

get

Added in v2.0.0 Source

Reads the current value of the TxRef.

When to use

Use to read the current value of a TxRef.

Signature

declare function get<A>(self: TxRef<A>): Effect<A>

Example

(Reading transactional references)

import { Effect, TxRef } from "effect"
const program = Effect.gen(function*() {
const counter = yield* TxRef.make(42)
// Read the value within a transaction
const value = yield* Effect.tx(
TxRef.get(counter)
)
return value
})
await Effect.runPromise(program) // => 42

modify

Added in v2.0.0 Source

Modifies the value of the TxRef using the provided function.

When to use

Use to update a TxRef and return a computed result from the same transaction step.

Signature

declare const modify: {
<A, R>(f: (current: NoInfer<A>) => [returnValue: R, newValue: A]): (self: TxRef<A>) => Effect<R>;
<A, R>(self: TxRef<A>, f: (current: A) => [returnValue: R, newValue: A]): Effect<R>;
}

Example

(Modifying transactional references)

import { Effect, TxRef } from "effect"
const program = Effect.gen(function*() {
const counter = yield* TxRef.make(0)
// Modify and return both old and new value
const result = yield* TxRef.modify(counter, (current) => [current * 2, current + 1])
return [result, yield* TxRef.get(counter)]
})
await Effect.runPromise(program) // => [0, 1]

set

Added in v2.0.0 Source

Sets the value of the TxRef.

When to use

Use to replace the value of a TxRef.

Signature

declare const set: {
<A>(value: A): (self: TxRef<A>) => Effect<void>;
<A>(self: TxRef<A>, value: A): Effect<void>;
}

Example

(Setting transactional references)

import { Effect, TxRef } from "effect"
const program = Effect.gen(function*() {
const counter = yield* TxRef.make(0)
// Set a new value within a transaction
yield* Effect.tx(
TxRef.set(counter, 100)
)
return yield* TxRef.get(counter)
})
await Effect.runPromise(program) // => 100

update

Added in v2.0.0 Source

Updates the value of the TxRef using the provided function.

When to use

Use to transform a TxRef when no result value is needed.

Signature

declare const update: {
<A>(f: (current: NoInfer<A>) => A): (self: TxRef<A>) => Effect<void>;
<A>(self: TxRef<A>, f: (current: A) => A): Effect<void>;
}

Example

(Updating transactional references)

import { Effect, TxRef } from "effect"
const program = Effect.gen(function*() {
const counter = yield* TxRef.make(10)
// Update the value using a function
yield* Effect.tx(
TxRef.update(counter, (current) => current * 2)
)
return yield* TxRef.get(counter)
})
await Effect.runPromise(program) // => 20

Constructors

make

Added in v2.0.0 Source

Creates a new TxRef with the specified initial value.

When to use

Use to create a TxRef inside an Effect workflow.

Signature

declare function make<A>(initial: A): Effect<TxRef<A>, never, never>

Example

(Creating transactional references)

import { Effect, TxRef } from "effect"
const program = Effect.gen(function*() {
// Create a transactional reference with initial value
const counter = yield* TxRef.make(0)
const name = yield* TxRef.make("Alice")
// Use in transactions
yield* Effect.tx(Effect.gen(function*() {
yield* TxRef.set(counter, 42)
yield* TxRef.set(name, "Bob")
}))
return [yield* TxRef.get(counter), yield* TxRef.get(name)]
})
await Effect.runPromise(program) // => [42, "Bob"]

makeUnsafe

Added in v4.0.0 Source

Creates a new TxRef synchronously with the specified initial value.

When to use

Use to construct a TxRef synchronously when it must be created outside an Effect workflow.

Signature

declare function makeUnsafe<A>(initial: A): TxRef<A>

Example

(Creating transactional references unsafely)

import { TxRef } from "effect"
// Create a TxRef synchronously (unsafe - use make instead in Effect contexts)
const counter = TxRef.makeUnsafe(0)
const config = TxRef.makeUnsafe({ timeout: 5000, retries: 3 })
// These are now ready to use in transactions
counter.value // => 0
config.value // => { timeout: 5000, retries: 3 }

Models

TxRef interface

Added in v4.0.0 Source

TxRef is a transactional value, it can be read and modified within the body of a transaction.

When to use

Use to store mutable state that must be read and modified inside Effect transactions.

Details

Accessed values are tracked by the transaction in order to detect conflicts and in order to track changes, a transaction will retry whenever a conflict is detected or whenever the transaction explicitely calls to Effect.txRetry and any of the accessed TxRef values change.

Signature

interface TxRef<in out A> extends Pipeable {
readonly "~effect/transactions/TxRef": "~effect/transactions/TxRef";
pending: Map<unknown, () => void>;
value: A;
version: number;
}

Example

(Using a transactional reference)

import { Effect, TxRef } from "effect"
const program = Effect.gen(function*() {
// Create a transactional reference
const ref: TxRef.TxRef<number> = yield* TxRef.make(0)
// Use within a transaction
yield* Effect.tx(Effect.gen(function*() {
const current = yield* TxRef.get(ref)
yield* TxRef.set(ref, current + 1)
}))
return yield* TxRef.get(ref)
})
await Effect.runPromise(program) // => 1