Xcode 27 is in beta right now (beta 4 at the time of writing), and it is a big release. Apple's official release notes are lots of lines of radar numbers and one-line bug fixes, which is great as a reference and terrible as a read.
Can you even run it?
Before anything else, check these three lines:
- Xcode 27 requires a Mac running macOS Tahoe 26.4 or later.
- Xcode 27 only installs and runs on Apple silicon Macs. If you are still on an Intel Mac, this release is the end of the line for you.
- On-device debugging supports iOS 17+, tvOS 17+, watchOS 10+, and visionOS. Older devices are no longer debuggable.
It ships with Swift 6.4 and the SDKs for iOS 27, iPadOS 27, tvOS 27, watchOS 27, macOS 27, and visionOS 27.
Part 1: The breaking changes (read this section)
I am putting these first because they are the parts that turn into a red build log on Monday morning. Everything else is upside.
Intel is being phased out of your build settings
If a target's minimum deployment target is macOS 27.0 or DriverKit 27.0, it will no longer build Universal by default. The ARCHS_STANDARD setting drops x86_64 once MACOSX_DEPLOYMENT_TARGET or DRIVERKIT_DEPLOYMENT_TARGET is 27.0 or higher.
If you still ship to Intel Macs, you have two options:
- Keep your minimum deployment target below macOS 27.0.
- Explicitly add
x86_64back to theARCHSbuild setting.
The macOS 27 SDK can still back-deploy Universal apps down to macOS 12, so this is a default change, not a hard removal.
The old linker is gone
ld64 has been removed and the -ld_classic flag is no longer supported. If you have that flag lingering in OTHER_LDFLAGS from some 2023-era workaround, delete it now. This one is a hard failure, not a warning.
On Demand Resources is deprecated
NSBundleResourceRequest and the whole On Demand Resources system are deprecated. The replacement is Background Assets, which got a solid round of improvements this release (more on that below).
PreviewProvider is deprecated
PreviewProvider and its family of preview modifiers are now deprecated. If you still have the old struct-based previews hanging around, this is your nudge to move to the #Preview macro.
Before:
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
After:
#Preview {
ContentView()
}
A real Swift source break
This one is subtle. A computed property that has both an init accessor and an array or dictionary literal as its initial value will no longer compile if the getter is declared before the init accessor. This is a known source break from SE-0508.
Broken:
struct S {
var _strings: [String]
var strings: [String] = ["hello"] {
get { _strings }
@storageRestrictions(initializes: _strings)
init { _strings = newValue }
}
}
The fix is to reorder: declare the init accessor first, then the getter. Annoying, but a one-line move.
Duplicate Clang module names now fail
The Swift dependency scanner was optimized to skip redundant header searches, and the tradeoff is that every Clang module reachable from a single dependency scan must have a unique module name. Previously the scanner tolerated duplicates; now it may error out.
The two situations that trigger this in the real world:
- An SDK or project that vends the same Clang module name from more than one location on the header search path.
- Vendored third-party sources shipping a
module.modulemapthat redeclares a module already in the SDK.
If you get a mysterious scanning error after upgrading, this is the first thing to check.
C++ changes worth knowing
If you have C++ in your app, a few things moved:
- The minimum macOS deployment target for the C++ standard library is now 11.0.
-
multimap::findandmultiset::findno longer guarantee returning an iterator to the first equal element. libc++ used to do this by accident, and the Standard never promised it. Uselower_boundorequal_rangeif you were relying on it. -
lower_boundandupper_boundonstd::mapandstd::setbehave differently for comparators that are not a strict weak order. Defining_LIBCPP_ENABLE_LEGACY_TREE_LOWER_UPPER_BOUNDgets the old behavior back, but that escape hatch is going away, likely next release. -
bitset::operator[]now returnsbool, which is actually what the Standard says it should do. -
std::allocatoris now trivially default-constructible.
The upside is significant: associative and unordered containers got up to 11x faster in some functions, several algorithms got up to 3x faster, and distance on non-random-access segmented iterators improved dramatically. A number of C++ papers landed too, including std::optional<T&>, zip, and std::views::indices(n).
Part 2: Agentic coding is now a first-class citizen
This is the headline feature, and it is a lot more than a chat box.
The assistant moved out of the sidebar
The coding assistant now lives in the editor area, not the navigator, with a redesigned conversation transcript. Artifacts the agent produces (code diffs, plans, SwiftUI preview snapshots) show up next to the transcript, and you can annotate code snippets and plan documents to give targeted inline feedback without leaving the conversation.
The sidebar is now dedicated purely to organizing conversations: real-time status, unread indicators, drag-and-drop grouping, archiving, renaming, multi-select for bulk actions, and a context menu to open conversations in new tabs, windows, or editor panes.
There is also a New Conversation button in the toolbar that works from anywhere in Xcode, with a status indicator you can click to jump to whichever conversation needs your attention.
Plan mode
Planning is now a proper feature rather than a prompting trick. Plans appear as editable Markdown artifacts next to the conversation. You review, annotate, discuss changes, and approve before the agent writes any code.
This is the workflow I would recommend for anything non-trivial: get the plan right first, then let it execute.
Agents can actually run your app
This is the part that changes what agents are useful for. In Xcode 27, agents can:
- Boot simulators, install and launch apps, synthesize touch events, and capture screenshots to verify UI behavior.
- Manipulate the active run state, read and interact with the debugger console.
- List and switch between schemes and run destinations.
- Inspect and modify build settings, compiler flags, entitlements, and Info.plist keys.
- Access project insights such as crashes, disk writes, energy, hangs, and launch issues affecting your shipped app.
In other words, an agent can now write a fix, build it, run it, look at the screen, and check whether it worked.
Gemini, ACP, and plugins
- Google Gemini is now available in the coding assistant alongside the existing options.
- Xcode supports the Agent Client Protocol (ACP).
- Agents can be extended with plugins containing skills, MCP servers, and ACP agent configurations. Skills are invokable as slash commands with completion support.
- Apple ships its own specialists for targeted tasks like localization, UIKit resizing, and accessibility.
- Two security-focused skills landed in beta 3:
adopt-c-bounds-safetyfor a file-by-file-fbounds-safetyadoption workflow, andaudit-xcode-security-settingsto suggest security-oriented build settings and entitlements.
Plugin authors can customize how their MCP servers appear in the UI using _meta fields:
{
"name": "MyGreatPlugin",
"description": "An awesome MCP server configuration.",
"version": "1.0.0",
"mcpServers": {
"MyGreatMCP": {
"type": "http",
"url": "...",
"tools": ["*"],
"_meta": {
"ideToolIconPath": "./icon.svg",
"ideToolIconRendersAsTemplate": true,
"ideToolTitles": {
"whoami": "Who Am I",
"get-current-email": "Get Current Email Message"
}
}
}
}
}
A sandbox for agents
Coding Intelligence includes a new security layer that monitors and controls filesystem access by coding agents and any processes they spawn. It is opt-in via Coding Intelligence settings. If you are nervous about letting an agent loose in your repo, turn this on before you do anything else.
One known issue to watch
If the "Implement the plan?" confirmation bar appears while the agent is still streaming, clicking Yes or No can start a new agent turn on top of the in-flight one and leave the conversation in a broken state. Wait for the agent to finish responding before confirming.
Part 3: Device Hub replaces the Simulator workflow
Device Hub is the new unified interface for both simulators and physical devices. Two features stand out.
Wireless pairing
You can now pair iPhone, iPad, and Apple Watch running OS 27 or later over a network. Click the + button in the Device Hub sidebar and choose "Pair Nearby Device". No cable needed for iPhone and iPad, and watch pairing is noticeably more reliable.
Mouse and trackpad gestures on iOS
Standard Mac gestures (scrolling, pinching, rotating) now work with UIKit components on iOS devices, physical or simulated.
There is a nuance worth understanding here. When you scroll with a pointing device, UIEvent.EventType.scroll is emitted. Pinch or rotate produces UIEvent.EventType.transform. But clicking with a mouse produces a simulated finger touch of type UITouch.TouchType.direct, not UITouch.TouchType.indirectPointer.
That is a convenience hybrid, not a faithful simulation. To validate real pointer behavior, use "Simulate Trackpad or Mouse" from the Device menu, test on a physical iPad with a paired pointing device, or use iPhone Mirroring.
Simulator boot is faster
Simulator runtimes now ship with a pre-built dyld cache, which makes the first launch of a simulator much faster. Small change, noticeable every single day.
Device Hub rough edges
Beta software, so expect some friction:
- Game controllers only work with the visionOS simulator.
- Video and input for a physical Apple Vision Pro are not supported (use AirPlay to view remotely). Everything else, like settings and DeviceFS, works.
- Two-finger touches cannot be sent.
- Scrolling over an Apple Watch face does not emulate the digital crown. Move the pointer over the crown in the bezel instead.
- Devices may not appear during parallel testing even though tests are running. Disable parallel runs if you want to watch UI tests execute.
- Downloaded app data containers land in a folder named after the bundle identifier rather than a proper
.xcappdatabundle. The workaround is to rename the folder with an.xcappdataextension and nest the contents inside anAppDatasubfolder.
Part 4: Previews and Playgrounds
Previews got real quality-of-life work this cycle.
Argument grids
#Preview(arguments:) renders a grid of previews, one per argument. Click any cell to open it in Interactive mode. This is great for state matrices.
#Preview(arguments: [
Order.empty,
Order.singleItem,
Order.manyItems
]) { order in
OrderSummaryView(order: order)
}
Resizable canvas
iOS previews get a Resizable Canvas mode so you can view your view in arbitrarily sized containers rather than fixed device frames. Helpful for adaptive layout work, and no longer constrained to specific size ratios.
Other improvements
- Each
#Previewand#Playgroundtab can be pinned independently in the canvas. - You can preview your UI in a different localization.
- Code inside
#Previewnow explicitly runs on the main actor, so calling main-actor-isolated APIs no longer produces concurrency warnings or runtime check failures. That was a real annoyance under strict concurrency. - Holding Command routes zoom and scroll events to the canvas. Toggleable via Editor > Canvas.
- Error messages across previews are meaningfully better: clearer timeouts, full diagnostics on MCP tool failures, and a placeholder view instead of a silent macOS fallback when a runtime is not installed.
Known issue: standalone Swift files opened by double-clicking in Finder may fail to run #Playground or #Preview blocks. Use File > Open, or drag onto the Dock icon.
Part 5: Localization becomes an agent workflow
This is probably the most immediately practical feature for small teams.
Agents can now translate strings in String Catalogs, from a single feature to an entire project, into one or more languages. Xcode handles the plumbing: it adds languages to your project settings, creates missing String Catalogs, and feeds context to the agent as it translates.
The String Catalog editor has a Generate Translations button, and you can right-click specific strings to translate just those.
Supporting changes that make this workable in a real pipeline:
- A localization comment of "do not translate" automatically marks the string as Don't Translate in String Catalogs and
translate="no"in exported XLIFFs. - Exported XLIFFs use
state-qualifier="leveraged-mt"to flag machine-translated strings, so your human translators know what to review. - You can annotate translations in String Catalog artifacts when agents are translating.
- Exporting localizations now extracts
NSLocalizedStringand similar macros from header files, not just implementation files. That is a fifteen-year-old bug report finally closed. - The "Prepare Project for Localization" tool surfaces newly added strings as artifacts, and shows keys removed because they no longer appear in source.
The honest take: this handles the bulk of the work, but you still want a professional translator reviewing the output before you ship to a new market.
Part 6: Instruments got a serious upgrade
If you do performance work, this might be the most valuable section of the release.
Swift Concurrency tooling
- A new Swift Executors instrument shows tracks for the Cooperative Thread Pool, the Main Actor, and any type conforming to
TaskExecutororSerialExecutor. Full capture on OS 27; older systems show "Unknown executor". - Task tracks now group into Swift Task Collections, sorted by name or creation site. You can switch a collection track between showing task lifetimes and task states.
- Tasks, Collections, Actors, and Executors have a Profile detail showing a call tree built from data captured while the task was running. Requires recording alongside Time Profiler or CPU Profiler.
- Selecting a bar chart interval in an Actor or Executor queue plot lists the waiting tasks in the inspector.
- Tasks and Actors whose lifetime started before the trace now show up, on a best-effort basis.
-
language swift task treein LLDB prints a tree of every Swift Task the debugger knows about.
Foundation Models instrument
New instrument for tracing and debugging Foundation Models usage: instructions, prompts, responses, token usage, and inference performance. If you are shipping on-device AI features, you now have visibility into them.
System Trace and QoS
System Trace unifies system calls, VM faults, and thread states into a single plot, with a blending algorithm that keeps dense regions readable when zoomed out. You can walk the chain of scheduling events for a thread with left/right arrow keys, and the inspector offers quick actions like pinning the thread that made another thread runnable.
The System Trace template also graphs thread priority over time, which makes priority inversion and resource starvation much easier to spot. Thread Activity now displays effective QoS by default, with requested QoS available from the track dropdown.
Everything else in Instruments
- Graphs no longer rescale to the local maximum when you pan the timeline, so comparisons across tracks are consistent. Manual rescale is under View > Rescale.
- Pinned tracks are restored from the previous run, and can be saved and restored explicitly via View > Track States.
- A new inspector shows details for the selected event with quick actions for pinning, filtering tracks, and filtering the detail view.
-
os_logdata can be overlaid on process and thread tracks via the Track Graph Display popover. -
os_signpostgets a track per signpost name, nested under the category. - The SwiftUI instrument records more detail about layout passes and why a layout computation was not cached, plus a "Summary of Updates" focus action on the view hierarchy.
- Allocations marks tagged allocations with a
(tagged)suffix when the process runs with Memory Integrity Enforcement. - Drag and drop
.atrc,.logarchive, or.samplefiles onto the sidebar to create a run for each. - Memory usage when importing
.atrcfiles dropped by roughly 1.5 GB on average. - Animation Hitches supports visionOS 27.0 and later.
On the command line, xctrace record accepts recording options as JSON (--show-recording-options prints the available ones), xctrace export can restrict a time range, and export now takes .atrc and .logarchive directly instead of requiring an import step first.
Deprecation: Instruments now requires iOS 17, watchOS 10, or tvOS 17 as a minimum on target devices.
Part 7: Organizer and production insights
The Organizer quietly became a planning tool rather than a crash dump viewer.
- Insights Overview summarizes high-impact performance regressions across metrics and diagnostic reports, so you can prioritize instead of guessing.
- The Hitches metric replaces Scrolling and covers all animations in your app, not just scroll.
- Storage metrics track Documents & Data and app size across releases, which catches cache bloat and bundle growth.
- AI-driven analysis generates recommendations for Crash, Energy, Disk Write, Hang, and Launch diagnostics, with links into your source and the coding assistant.
- Metric goals now cover Battery Usage, Disk Writes, Hang Rate, Hitches, Memory, and Storage. Similar-app goals are supported for Hang Rate, on-screen Battery Usage, Disk Writes, and Storage, and Launch Time baselines were recalibrated.
Combined with agents having access to these insights, the loop is: Organizer flags a hang regression, you ask the agent about it, the agent reads the diagnostic and proposes a fix.
Part 8: Testing
-
XCUIVoiceOverServiceis a new UI testing API for verifying VoiceOver behavior. You can drive VoiceOver from UI tests and assert on focus, spoken output, and navigation. Accessibility testing that actually tests accessibility. - A launch test file template that opts into
runsForEachTargetApplicationUIConfiguration, so the test runs across every combination of orientation, localization, and appearance your app supports. - Test plans let you choose how the system responds when the target app crashes during UI testing: off, warning, failure (the default), or fatal failure.
- Mixing frameworks now warns you: calling an XCTest assertion inside a Swift Testing test (or the reverse) produces a warning-severity runtime issue. Configurable via the new interoperability setting in your test plan.
- Filters were added to the test plan configurations tab, plus recent tests and open tests filters in the Test Navigator.
- Large Swift Testing suites with many parameterized cases perform significantly better.
- Test Repetition Mode now repeats individual Swift Testing cases instead of the whole test plan.
On the SwiftPM side, swift test summarizes failures at the end of a run, and supports --maximum-repetitions with --repeat-until [pass|fail] for hunting flaky tests. Only cases matching the condition get repeated.
swift test --maximum-repetitions 20 --repeat-until fail
Part 9: Everything else worth a mention
Interface Builder builds without a simulator
A new IB compilation mode, toolchain, is enabled by default for UIKit documents. It compiles IB documents without downloading a simulator, which is a genuine win for CI and build servers.
Background Assets
Since On Demand Resources is deprecated, this matters:
- Asset-pack manifests support path wildcards, file exclusion, hard-coded source roots, and custom destination subpaths.
- Localized asset packs: the system delivers only the packs matching the user's preferred languages, cutting storage usage.
- A Steam Asset Converter turns Steam depots into asset packs.
- Xcode can serve asset packs to your app while debugging on device. Set a Background Asset Packs folder in the Run scheme action's Options tab.
StoreKit testing
- New configuration UI for In-App Purchase offer codes, plus off-device purchase options to test them through the Transaction Manager.
- Subscription Bundles and Subscription Suites can be configured for local testing.
- Volume purchase transactions can be created for 1-month and 1-year auto-renewing subscriptions.
Swift and C++ interoperability
- C++ constructors with default parameter expressions no longer require passing every argument explicitly from Swift.
- Swift closures convert to
std::functioninstances. -
__counted_byand__noescape-annotatedstd::spanparameters map to SwiftSpanwithout the experimental feature flag. Return values via__lifetimeboundstill need it. - Safe wrappers can be generated for functions taking
std::spandirectly, without hiding the instantiation behind a typedef, as long as the parameter is__noescape. - The new
SWIFT_REFCOUNTED_PTRmacro bridges smart pointers to intrusively reference-counted types into Swift classes.
Debugging
- LLDB can inspect data types with
~Copyablefields in the standard library and system frameworks. - LLDB ships with an MCP server (
lldb-mcp). - In projects using bridging headers, LLDB imports explicitly built Swift modules and PCH from DerivedData directly. This can dramatically speed up the first
poin a debug session, which has historically been painfully slow.
Documentation search
You can search developer documentation using natural language, with results matched semantically rather than by keyword.
Icon Composer 2.0
Supports a sharper rendering mode for the 2027 operating systems, with refractivity, outside specular, and deeper shadows. Edit the new properties in the group inspector and preview either design generation from the toolbar. One icon covers all OS versions.
Migration checklist
If you want the short version, here it is:
- Confirm you are on an Apple silicon Mac with macOS Tahoe 26.4+.
- Remove
-ld_classicfrom your linker flags. - Decide your Intel story: lower your deployment target, or add
x86_64toARCHSexplicitly. - Migrate
PreviewProviderto#Preview. - Plan the move from On Demand Resources to Background Assets.
- Check for duplicate Clang module names if dependency scanning starts failing.
- Fix any
initaccessor ordering issues flagged by the Swift compiler. - If you use C++, audit
multimap/multisetfindusage and any custom comparators. - Turn on the agent filesystem security layer before letting agents run.
- Drop your minimum device targets for testing to iOS 17 or later.
Reference
Source: Xcode 27 Release Notes
Top comments (0)