# Stop using @unchecked Sendable

**URL:** <https://forums.swift.org/t/stop-using-unchecked-sendable/88629>\
**Category:** Community Showcase\
**Tags:** concurrency, actors, swift6, strict-concurrency\
**Created:** [July 29, 2026, 4:07pm UTC](https://forums.swift.org/t/stop-using-unchecked-sendable/88629 "2026-07-29T16:07:47Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![soumyamahunt](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/soumyamahunt/32/23427_2.png) [@soumyamahunt](https://forums.swift.org/u/soumyamahunt)\
**Post date:** [July 29, 2026, 4:07pm UTC](https://forums.swift.org/t/stop-using-unchecked-sendable/88629/1 "2026-07-29T16:07:47Z")

</div>

While migrating a large SDK to the Swift 6 language mode, I wanted to avoid blanket `@unchecked Sendable` on our existing lock-guarded types. The pattern I landed on: implement `SerialExecutor` over `NSRecursiveLock` (jobs run inline on the calling thread under the lock), then back a nested `@globalActor` with it so the enclosing type can stay a `class` with a synchronous API while its state becomes compiler-isolated.

The write-up covers the executor, recursive-lock reentrancy and `owner` restoration, `checkIsolated()` / `isIsolatingCurrentContext()`, and a synchronous `run` entry point.

I'd genuinely value any feedback:

> **[Stop using @unchecked Sendable](https://soumyamahunt.medium.com/stop-using-unchecked-sendable-2e00bd6cb122)**
>
> How a SerialExecutor lets you keep your lock and get Swift’s data-race safety too.

---

<div class="post-metadata">

**Author:** ![kelin](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/kelin/32/21678_2.png) [@kelin](https://forums.swift.org/u/kelin)\
**Post date:** [July 29, 2026, 4:39pm UTC](https://forums.swift.org/t/stop-using-unchecked-sendable/88629/2 "2026-07-29T16:39:24Z")

</div>

Clickbait title.
