Hacker News new | ask | show | jobs
by willtemperley 141 days ago
Most Swift compilation slowness can be avoided by componentizing using packages, plus a few tricks like being explicit with types rather than relying on type inference.

I’m not sure why you’re having so much trouble with SPM though, most people seem to get on well with it.

6 comments

I'm also wondering how big their programs are that the compile times are an issue. I'm seeing fantastic build times with Xcode 16 and Xcode 26.2 with swift 6.2 it's even better. SPM is also better with the newer version. Most issues can be solved or exposed by closing the window and reopening or going to the package with issues and pressing cmd+s.
Trying to make a .xcframework from SPM is "fun". And getting the Objective-C that are generated, but treated as intermediary artifacts discarded is a bit of a pain.

But I guess the issue here is that .xcframework is an Apple thing, not a Swift thing.

The whole "won’t build if the product / target has the same name as one of its classes" is absolutely ridiculous on the other hand.

Try xccache
Experience with SPM might vary depending on how many dependencies you’ve got. A lot of Apple platform apps are quite thin on third party library use, in which case SPM is probably not a large source of trouble.
My problem with it is that I want to use C libraries. And I would (like) it to handle that as much as possible. But SPM can't use vcpkg packages or call CMake stuff (at least, not trivially), so it's extremely hard to use on non-Apple platforms. Which honestly is it's killer for me. It's still so, so Apple focused.
You can build Swift entirely with CMake;

https://github.com/swiftlang/swift-cmake-examples

Sure, but I've never found examples of (say) including other swift packages. Or using CMake-built swift packages in SPM.
What is a CMake-built swift package to begin with? You're mixing build systems and expecting them to co-exist or what is the exact problem? I've done a lot of weird swift things so might be able to point you in the right direction.
E.g.: referencing a vcpkg-built package (without pkgconfig because not all packages have those files). Or telling SPM "Hey, I have this package which uses the cmake build system, and I want you to link to it and auto-generate module maps for it, and get the include directories from cmake". Things like that. So for me anyway it makes using swift painful. The same thing goes in reverse: using SPM packages from cmake (although this is more a cmake issue).
I think cmake very recently got added to spm
As your app scales, you're going to want to break out different parts into their own packages in order to keep compile times in check, so you're gonna be forced to go through SPM unless you use tuist or bazel.
Xcode (and as of a couple years ago the vscode spm integration) tends to have difficulty when scaling this solution.

Being explicit with types is very disruptive when used in SwiftUI or TCA.

I'm just talking about having some mechanical sympathy for the compiler such as understanding where the constraint solving problem space gets very large.

I wasn't saying use explicit types everywhere, but giving the compiler a hint every now and then to make things faster just makes sense. The Swift compiler is very complex and of course there are edge cases where it struggles with legal syntax, such as large expressions with many operators.

With SwiftUI it's arguably more important because view builders already put a lot of strain on the compiler.

You can't really easily use explicit types in much of idiomatic SwiftUI. The expression that the compiler is trying to solve is really complicated, I agree, but the solution to that is either changing how SwiftUI is architected or restricting how the language built on SwiftUI infers types.
Using explicit types is less fun though
It even defeats the purpose of type inference.
It's been a while since I've Swifted but it was mostly with combinations of nested generics, lambdas, and literals. Annotating the type of the variable those were assigned to could improve performance a lot.

You don't need to add an annotation on `let foo = bar()` where bar is a function that returns `String` or whatever.

SPM is fine for most Swift and then fully enraging when you have a slightly divergent use case. IME of course.