Show HN: Skip – Build native iOS and Android apps from a single Swift codebase (skip.tools)
What it is: Skip stands in contrast to other cross-platform development tools like Flutter, React Native, and Xamarin, in that it enables the creation of genuinely native applications for both of the dominant mobile platforms. It doesn't embed a separate engine or runtime into your app, but instead lets you use pure Swift and SwiftUI to create the iOS side of the app (as per Apple's recommended best practices for creating iOS apps), and transpiles it into a pure Kotlin and Jetpack Compose app for the Android side (which is Google's recommendation for building Android apps). So your application will use platform-native controls and will automatically have all the affordances provided by the platform vendor: animations, accessibility, and future-proof evolution alongside OS updates.
How it works: you build a Skip app using the same tools that you use to create a standard iOS app: Xcode, Swift, and SwiftUI. Skip augments this workflow with a Swift Package Manager plugin called "skipstone", which transpiles your Swift into Kotlin each time you build your app, and launches the Android app side-by-side with the iOS app each time you run the app. The transpilation works not just on your primary app module, but also transitively processes all your dependent SwiftPM modules, so you can break complex projects down into individually testable sub-modules containing business logic or UI code. In fact, this is how our own adaptor modules for the standard frameworks are structured: SkipFoundation adapts the Foundation framework and SkipUI adapts the SwiftUI framework, so the same familiar API can be used when building the app. And there's a GitHub ecosystem of open-source modules supporting popular frameworks, including SQLite, Firebase, Lottie, and many other common building blocks of modern apps.
Over the past year Skip has evolved into a fully-capable solution for creating best-in-class apps for both iOS and Android. And today we are delighted to announce the release of version 1.0, meaning that it is ready for production use.
We have a wealth of videos and documentation available at https://skip.tools, and I'll be around to field any questions that any of you might have. Thanks in advance for taking a look!
Home: https://skip.tools
FAQ: https://skip.tools/docs/faq/
GitHub: https://github.com/skiptools/
120 comments
[ 3.2 ms ] story [ 173 ms ] threadLooking at the docs gives a good overview of how it works.
Regarding transpilation and the tradeoffs (https://skip.tools/topic/transpilation-tradeoffs/), does the limitation of certain Swift features cause any significant friction with using parts of SwiftUI or other core libraries?
Wondering how much those (understandable) limitations on the transpilation limit what a random iOS dev might be able to do compared to what they can do in iOS land.
Also, using SwiftUI cross-platform makes me think that many android libraries would be a no-go.
One of the reasons that Xamarin development was painful (other than the numerous bugs in trying to target 2 foreign platforms) was that you couldn't _really_ utilize the large native ecosystems of either platform, and you would end up spending a lot of time "rewriting" libraries in dotnet.
> Also, using SwiftUI cross-platform makes me think that many android libraries would be a no-go.
A unique feature of Skip is that the Kotlin/Android side is free to integrate with whatever gradle libraries it wants (see https://skip.tools/docs/dependencies/). Similarly, the Swift side can have any SwiftPM dependencies it wants.
Only your own transpiled modules, and the core Skip modules, will need to support transpilation. You can then include any native dependencies via your app's transpiled code that branches based on which platform/language you are targeting. So, for example, the Swift/SwiftUI side of the project can depend on the SwiftPM "https://github.com/firebase/firebase-ios-sdk.git" dependency, and the Kotlin/Compose side can depend on the Gradle "com.google.firebase:firebase-bom" dependency. This is what we ourselves do in the various integration modules we have (such as SkipFirebase, for this particular example).
Doing something non-standard hints bugs to me.
No "built with" list yet, but coming soon…
Note that Skip doesn't put any constraints on the iOS side of your app at all: if it can be expressed with SwiftUI or UIKit, then you can do anything. If there are bits that SkipUI doesn't translate to your liking (or at all), you can always drop down directly into Kotlin and Jetpack Compose to implement those any way you want. See https://skip.tools/docs/platformcustomization/ for details.
In other words the Swift app will keep developing, requiring constant Android app generation via transpilation.
Does it keep track of generated and manually edited parts or will that step on each other?
This fixes the big painpoint that nowadays' cross-platform frameworks come with performance tradeoffs as they have a unified presentation layer!
Are you sure
I guess one ugly mobile app IDE is better than two.
The issue we ran into is that we've already built a native iOS app with SwiftUI + a bit of UIKit. Integrating Skip with an existing app seemed like a significant task
Does that hold true in your experiences? Do you have any examples of small- or medium-sized existing apps that have migrated to Skip?
https://skip.tools/docs/gettingstarted/#existing_development
Is it not just a transpiler, since then it should work at any stage. No?
After testing the feasibility of other cross-platform frameworks, I landed on Skip. I LOVE that I don't have to break out of the "Swift" mental context, I just have to focus on writing an app in 1 language.
So before I commit fully I've been testing it out (building a demo app this week) and so far I am very impressed. The syntax to write platform-specific code (#if !SKIP #endif) is very easy to use once you get the hang of it.
It's amazing I don't have to learn Android to get something up and running at this speed with Skip. Hitting run in xcode and watching both emulators open feels like magic. I want to put this to the test so I plan to build a complete App with it from start to finish, ship it to both App Stores, and if all that goes smoothly I will proceed to migrate my main app using Skip.
Any thoughts on how you would debug issues on Android that don’t show up on iOS?
We wouldn't say that is the point of using Skip. The benefit you get from using Skip is that you can use a single language and a single framework for building your app, and you can iterate on your app's development without needing to constantly context-swift between different worlds.
But there is no denying that at some point, you will need to interact with the Android universe: you will need to run the app on an Android emulator or device to test it, you will need to use Android Studio (or IntelliJ) to run the app in a debugger, you will need to grapple with the Android-specific nuances of deploying you app to the Play Store.
Or re-patch them in some way?
Been a long time since I worked on mobile (pre Kotlin!) but how does it handle differences in the UIs. Do you need "is android" directives. Are there Swift objects in your library that are android specific.
That being said, there is often plenty of need for customization with any but the most trivial app. So Skip has a lot of options for that, which is covered in the Platform Customization guide at https://skip.tools/docs/platformcustomization/.
Lots of options for adding platform-specific code - including being able to directly call Kotlin/Java APIs from your Swift, move back and forth between SwiftUI and Compose, etc.
https://skip.tools/docs/platformcustomization/
On the Swift/iOS side, it simply uses Swift's excellent C integration; on the Java/Android side, it uses the venerable JNA library to handle loading and calling into embedded native libraries.
The website is very slow to scroll on phone for some reason. Feels like scrolling has smoothing effect applied on it which does not work well everywhere and ends up slowing down scrolling (feels like 10 fps or something).
Please feel free to point to a doc that may already answer that.
That being said, while we have good translation coverage at both the lower levels (Foundation to the Android SDK) and higher levels (SwiftUI to Jetpack Compose), there are many Apple frameworks that we simply don't have any compatibility frameworks for yet. One commonly-request example is maps: we don't have anything that takes the MapKit API and converts into the Google Maps equivalent. However, this doesn't prevent you from implementing it yourself. For a simple example, see the Travel Bookings sample demo at 2:15 at https://skip.tools/tour/skip-showreel/, where you can see how you can drop MapKit and Compose Maps inline into your code.
As time goes on, Skip's community ecosystem of compatibility frameworks will grow and expand. But until then, there aren't any barriers to simply implementing them yourself.
I would just like to ask, what Material version are you using?
If I may suggest, instead of 6 month audit and machine locked license, perhaps something like where license is needed IFF the app is launched. This will reduce friction for individuals and pre-funding startups. I believe Unity and Unreal use this kind of licensing.
They need to build critical mass and hence initial tinkering should be as friction free as possible. Landscape is full of alternatives so people need to get started as quickly as possible.
They seem to have a valuable product, but this initial friction might reduce traction, again IMHO.
Now of course Skip can't have complete Android coverage for every iOS framework - far from it. So if you use something on the iOS side that has no Android coverage, you have to create a separate code path for Android, where typically you'll utilize an equivalent Android framework/function. Skip has several mechanisms for integrating Android code, including being able to call Kotlin and Java API directly from your Swift. These mechanisms are also how you can differentiate parts of your Android app as desired, and how we create our own cross-platform libraries.
Have you addressed that with Skip?
Looks incredible, btw. :)
I am thinking about making an app, and we want to support the best offerings from each OS. So the dynamic colors is important on the Android side
We’ve been thinking about KMP til I read about this, which sounds promising!
1. Open-source, it mentions GPL forms, is there a reason MIT not mentioned? is that not considered open-source (especially with many iOS/Swift using MIT to be compliant with store distribution).
2. Packages, how does it handled packages? or the cases when you need to have branching for iOS/Android? the FAQ does not address this.
3. How Apple service APIs being handled on Android? I didn't look at the example weather app, but as an example, Apple got WeatherKit. or in my case case I use the built-in geolocation APIs.
My concrete example, I have a small app I've made. It uses geolocation from Apple (to detect country city, etc), It uses AdMob and Apple's built-in In-App / Subscription services.
I think this is a fair example of simple commercial product, and it'll be nice if you have some example for ads and in-app/subscription which might be important for closed/paid monetized projects...
- Skip is based on Swift Package Manager and fully both dual-platform and iOS and Android-specific dependencies.
- Skip has a suite of dual-platform libraries, and for anything that isn't covered, multiple techniques for integrating platform-specific code and libraries. These include being able to use Kotlin right inline with your Swift and mix Compose code in with your SwiftUI.
https://skip.tools/docs/platformcustomization/
https://skip.tools/docs/dependencies/#implementation