
The official Swift extension for VS Code (`swiftlang.swift-vscode` v2.16.5, 640,700+ installs, 5.0 rating) gives SPM project developers full language server support via SourceKit-LSP, LLDB-based debugging, and a Test Explorer with five execution modes — including run-with-coverage and run-until-failure. The article walks through prerequisites, a complete Package.swift + XCTest/Swift Testing code demo, the coverage instrumentation workflow, a `launch.json` debug config example, and an honest breakdown of the three hard limits: SPM-only (no `.xcodeproj`), Windows debugging bugs, and 12 open issues.
swiftlang.swift-vscode extension (v2.16.5, 640,700+ installs, 5.0 rating) is the only extension you need. It ships SourceKit-LSP (Apple's Swift language server, bundled with the toolchain), LLDB-based debugging, a full Test Explorer, and SPM project management — all wired together with zero manual LSP configuration. 1sswg.swift-lang at v2.0.0 (February 2025). If you still have the old one installed, it now shows as "Swift (Deprecated)" — remove it and install under the new publisher. 2Package.swift; the extension auto-activates on detectionllvm-vs-code-extensions.lldb-dap (the LLDB Debug Adapter Protocol extension from the LLVM project) as a required dependency. You don't install it separately. 3Package.swift in the root folder. Open that folder in VS Code and the extension loads the package graph, populates the Swift Packages panel in the sidebar, and generates launch configurations for every executable target automatically.Cmd+Shift+P / Ctrl+Shift+P) and run Swift: Create New Project. A picker offers Library, Executable, Tool, System Module, and Plugin templates.Swift 6.0 and earlier: SourceKit-LSP indexes your code lazily. Code completion and go-to-definition may not work until you run a build. Open the integrated terminal and runswift buildonce — the language features activate immediately after indexing completes. Swift 6.1+ introduced background indexing that handles this automatically. 4
XCTestCase and @Test function in your package automatically, with no configuration file required.| Mode | What it does |
|---|---|
| Run Test | Runs the selected test(s), reports pass/fail in the sidebar |
| Debug Test | Starts LLDB and pauses at any breakpoint you've set in the test or source code |
| Run Test with Coverage | Instruments the run and opens an inline coverage view afterward |
| Run Multiple Times | Runs the selected test N times — useful for flaky test detection |
| Run Until Failure | Keeps running until the first failure — for reproducing intermittent bugs |
▶ Run | Debug) appear inline above each test function in the editor too. Toggle them off with swift.showTestCodeLenses: false if you find them noisy. 2
Package.swift that declares both a library target and a test target:// swift-tools-version: 6.0
import PackageDescription
let package = Package(
name: "MySwiftTool",
targets: [
.executableTarget(name: "MySwiftTool"),
.testTarget(
name: "MySwiftToolTests",
dependencies: ["MySwiftTool"]
),
]
)Tests/MySwiftToolTests/. The extension discovers them automatically on save.import XCTest
@testable import MySwiftTool
final class MySwiftToolTests: XCTestCase {
func testAddition() throws {
XCTAssertEqual(1 + 1, 2)
}
}Testing module):import Testing
@testable import MySwiftTool
@Suite struct MySwiftToolTests {
@Test("addition works correctly", .tags(.critical))
func addition() {
#expect(1 + 1 == 2)
}
}@TestTarget:critical in the Test Explorer search box to run only tests tagged .critical. 4testTarget's sources, meaning the library or executable the test target imports. Coverage data for the test file itself (the assertions) is not the useful part. 6Package.swift — they appear in the Run and Debug dropdown immediately on project open. For a custom configuration, .vscode/launch.json takes type: "swift":{
"configurations": [
{
"type": "swift",
"name": "Debug MySwiftTool",
"request": "launch",
"program": "${workspaceFolder}/.build/debug/MySwiftTool",
"args": [],
"cwd": "${workspaceFolder}",
"preLaunchTask": "swift: Build Debug MySwiftTool"
}
]
}${binPath} variable that resolves to the build output directory automatically, so you can write "program": "${binPath}/MySwiftTool" instead of hardcoding the .build/debug path. 2#expect() / XCTAssertEqual() rarely fire at a useful location), then use Debug Test from the right-click menu in Test Explorer.
.xcodeproj) get limited support at best. 5 If you're building iOS or macOS apps in Xcode and want VS Code integration, look at SweetPad (1.8k stars) instead — it wraps xcodebuild, uses CodeLLDB, and supports simulator management and device deployment.lldb-dap requires Python 3.10 to be installed separately. When it's missing, the debugger fails with an unhelpful error (open bug #2054). Breakpoints also have a separate open bug (#1871) where they may not install correctly in Swift Testing tests. If you're doing Swift on Windows, keep a terminal open for swift test and treat the debugger as best-effort. 7swift.sourcekit-lsp.includeDeclarationInFindAllReferences — when set to true, Find All References includes the declaration site itself in results (default is false, matching LSP standard behavior)swift-build multi-target test timeouts, swiftly/xcrun toolchain execution paths, and a bug where swift.buildPath was ignored by plugin tasks. 2marketplace.visualstudio.com
github.com
raw.githubusercontent.com
code.visualstudio.com
github.com
github.com
github.com
This story was produced automatically by a channel. One sentence is all it takes for Neodrop to keep producing for you.