All images in this article are AI-generated by the author with NightCafe Studio.

Introduction

Go, often referred to as Golang, has earned its distinguished reputation through a combination of elegant simplicity, raw performance, and powerful concurrency models.

A truly transformative, yet often understated, feature of Go is its innate and robust support for multiplatform programming.

The ability to write a single codebase and compile it for a diverse landscape of operating systems and architectures with minimal effort is a paradigm shift for developers.

This guide provides a deep dive into using Go for cross-platform development, covering desktop and mobile targets, including:

The Core Principle: GOOS and GOARCH

At the very heart of Go's cross-compilation magic are two fundamental environment variables: GOOS and GOARCH.

These variables act as simple yet powerful directives for the Go compiler, instructing it on the precise operating system and processor architecture for the intended binary output.

This streamlined approach, a standard feature since Go 1.5, has made a historically convoluted process remarkably straightforward.

To discover the complete matrix of supported platform and architecture combinations for your specific Go installation, you can run a simple diagnostic command.

go tool dist list

This command queries the Go toolchain and prints an exhaustive list of every possible target, demonstrating the vast and versatile reach of the Go compiler.

aix/ppc64
android/386
android/amd64
android/arm
android/arm64
darwin/amd64
darwin/arm64
dragonfly/amd64
freebsd/386
freebsd/amd64
freebsd/arm
freebsd/arm64
illumos/amd64
ios/amd64
ios/arm64
js/wasm
linux/386
linux/amd64
linux/arm
linux/arm64
linux/mips
linux/mips64
linux/mips64le
linux/mipsle
linux/ppc64
linux/ppc64le
linux/riscv64
linux/s390x
netbsd/386
netbsd/amd64
netbsd/arm
netbsd/arm64
openbsd/386
openbsd/amd64
openbsd/arm
openbsd/arm64
openbsd/mips64
plan9/386
plan9/amd64
plan9/arm
solaris/amd64
windows/386
windows/amd64
windows/arm
windows/arm64

This stunned me the first time I saw it and still stuns me today!

Golang Tooling and Developer Experience

One of Go's most celebrated features is its integrated and opinionated toolchain, which creates a highly productive and consistent developer experience.

The toolchain is included in the standard Go distribution, requiring no separate installation or complex configuration.

go build:

go fmt:

go test:

go mod:

This cohesive set of tools lowers the barrier to entry and allows developers to focus on writing code rather than configuring their environment.

Compiling for Desktop Platforms

Generating executables for traditional desktop environments represents the most direct application of Go's cross-compilation features.

The process yields single, statically-linked binaries with no external runtime dependencies, which simplifies distribution immensely.

Compiling for Windows from Linux/macOS

To produce a self-contained executable file for the Windows platform, you only need to set the GOOS environment variable to windows.

For modern 64-bit Windows systems:

GOOS=windows GOARCH=amd64 go build -o myapp-amd64.exe .

For legacy 32-bit Windows systems:

GOOS=windows GOARCH=386 go build -o myapp-386.exe .

The resulting .exe files can be run directly on any target Windows machine without needing to install a Go runtime, a key advantage for user convenience.

Compiling for Linux from Other Platforms

In a parallel fashion, targeting the Linux operating system is as simple as setting the GOOS variable to linux.

You can compile for numerous processor architectures, with amd64 for servers and desktops and arm64 devices like the Raspberry Pi are extremely common.

For 64-bit Linux on x86 architecture:

GOOS=linux GOARCH=amd64 go build -o myapp-linux-amd64 .

For 64-bit Linux on ARM architecture:

GOOS=linux GOARCH=arm64 go build -o myapp-linux-arm64 .

These binaries are ready for immediate execution on any Linux distribution matching the specified architecture.

Compiling for macOS from Other Platforms

To compile an application for macOS, you set the GOOS variable to darwin.

The macOS platform has notably transitioned from Intel (amd64) processors to Apple's custom ARM-based Silicon (arm64), and Go can target both.

For Intel-based Mac computers:

GOOS=darwin GOARCH=amd64 go build -o myapp-macos-amd64 .

For Apple Silicon-based Mac computers:

GOOS=darwin GOARCH=arm64 go build -o myapp-macos-arm64 .

Creating a Universal Binary for macOS

To distribute a single application that runs natively on both Intel and Apple Silicon Macs, you can create a "universal" binary.

This process requires compiling for both architectures and then merging them with the lipo command-line tool, which is part of Apple's Xcode development environment.

Step 1: Compile for each separate architecture:

GOOS=darwin GOARCH=amd64 go build -o myapp-amd64 .
GOOS=darwin GOARCH=arm64 go build -o myapp-arm64 .

Step 2: Use the lipo tool to create the universal file:

lipo -create -output myapp-universal myapp-amd64 myapp-arm64

This single myapp-universal executable provides the best performance on all modern Macs by containing the native code for both processor families.

Diving into Mobile: Go on Android and iOS

Go's multiplatform capabilities extend into the mobile sphere via the gomobile tool, a specialized part of the Go ecosystem.

Crucially, gomobile can be used for building complete, working Golang mobile apps with basic UI capabilities using the golang.org/x/mobile/app package and OpenGL ES.

Setting up gomobile

First, you must install the gomobile tool and run its one-time initialization command to set up the required bindings and toolchains.

go install golang.org/x/mobile/cmd/gomobile@latest
gomobile init

For Android, you must have the Android NDK (Native Development Kit) installed.

For iOS, Xcode is required, and the build must be performed on a macOS machine.

Compiling a Go Library for Android

To compile a Go package into a standard Android Archive (.aar) library, you use the gomobile bind command.

This command inspects your Go package and generates the necessary Java interface code (the "binding") to make it callable from Kotlin or Java.

gomobile bind -target=android -o greeter.aar .

You can then import this greeter.aar file into your Android Studio project's libs folder and add it as a dependency.

This allows you to call your performant Go logic directly from your Android app code.

Compiling a Go Library for iOS

The process for iOS is analogous.

On a Mac, you run gomobile bind with the ios target.

This command generates an XCFramework, the modern, universal format for binary libraries on Apple's platforms.

gomobile bind -target=ios -o Greeter.xcframework .

You can then drag this Greeter.xcframework directly into your Xcode project.

Swift code can immediately import and use the functions from your Go package.

Go vs. Flutter/Dart for Cross-Platform Mobile Coding

Go and Flutter represent fundamentally different approaches to cross-platform development.

Go shares logic (and more rarely, UI), while Flutter shares both logic and UI.

Feature

Golang (with gomobile)

Flutter (with Dart)

Primary Use Case

Sharing non-UI code (business logic, networking, algorithms) as a native library.

Building complete, self-contained applications with a unified UI from a single codebase.

UI Strategy

Limited UI capabilities. Relies entirely on the native UI toolkits of the host platform (e.g., SwiftUI for iOS, Jetpack Compose for Android).

Provides its own comprehensive UI toolkit. Renders every pixel on the screen using its Skia graphics engine, bypassing native UI widgets.

Development Paradigm

Embed a foreign library into a native application. The core app is still native.

Write the entire application, including the UI, in Dart. The app is a Flutter app.

Performance

Excellent for raw computational tasks. The shared library runs as a compiled native binary.

Excellent UI performance (often 60/120fps). Dart can be JIT compiled for fast development and AOT compiled for fast release builds.

When to Choose

When you need to share highly performant, complex logic behind a fully native UI/UX, or when reusing existing Go backend code on mobile.

When your priority is building an application with a consistent, brand-centric UI across all platforms with maximum code reuse.

Go vs. Kotlin Multiplatform (KMP) for Cross-Platform Mobile Coding

Go and Kotlin Multiplatform (KMP) are more direct competitors, as both focus on sharing non-UI logic.

However, it must be noted that now Golang has support for GUIs as well.

The primary differences lie in language integration and ecosystem.

Feature

Golang (with gomobile)

Kotlin Multiplatform (KMP)

Primary Use Case

Both are used to share non-UI logic between platforms by compiling to native libraries.

Both are used to share non-UI logic between platforms by compiling to native libraries.

Language Integration

Always a foreign language. Communication happens across a bridge (FFI) automated bygomobile.

Native on Android (Kotlin-to-Kotlin). Excellent interop with Swift on iOS. Feels more like an extension of the native environment.

Development Paradigm

Embedding a separate ecosystem (Go) into native apps.

Extending the Kotlin ecosystem to other platforms. Logic is written in a common main source set.

Build System

Extremely simple and fast go build command.

Relies on Gradle, which is powerful and deeply integrated with Android Studio, but also significantly more complex and slower than Go's tooling.

Target Breadth

Excellent, mature support for a vast range of OS/architecture targets beyond mobile (servers, desktops, CLI, WebAssembly).

Primarily focused on Android and iOS, with desktop and WebAssembly support maturing. Less emphasis on server-side targets.

When to Choose

For performance-critical code, targeting a wide array of platforms, or when simplicity of the toolchain is a significant priority.

For teams heavily invested in the Kotlin ecosystem, especially for sharing logic between Android and iOS, where seamless language integration is key.

But now, of course, there are tools that allow you to build GUIs in Golang for mobile platforms as well.

Just donโ€™t expect Liquid Glass!

You can find some of them below:

Helpful Go Libraries for UIs, Distribution, and More

While Go's standard library is extensive, the rich third-party ecosystem provides powerful tools that simplify building user interfaces and distributing cross-platform applications. Here are ten valuable libraries that are instrumental in the Go multiplatform ecosystem.

Fyne

Wails

GoReleaser

Cobra

Gio

Viper

Zerolog

GoReleaser/nfpm

Afero

Conclusion

Go's multiplatform capabilities are a testament to its pragmatic design, offering a powerful and refreshingly simple solution for building and distributing software.

Its true strength lies not in replacing native UI development, but in augmenting it.

Go enables developers to write core business logic, complex algorithms, or networking stacks once, in a highly performant and concurrent language, and then deploy that logic everywhere.

Go empowers you to build fully native, platform-idiomatic UIs while sharing the complex, non-visual code that powers them.

The gomobile tool can even help you create complete mobile native apps that have basic UI features.

Go stands out with its unparalleled toolchain simplicity, lightning-fast compiler, and mature support for a vast spectrum of platforms beyond just mobiles.

By mastering Go's cross-compilation tools, developers gain a potent new strategy in their arsenal, enabling a hybrid approach that combines the performance of native code, the UX of native interfaces, and the efficiency of a shared cross-platform core.

Go is not just a language; it is a force multiplier for a truly multiplatform world.

What are you waiting for?

Start building your cross-platform application in Golang today!

References

  1. Go Official Documentation: The primary source for all information about the Go programming language.

    https://go.dev/doc/

  2. Go Commands Documentation: Official documentation for Go's command-line tools, including go build.

    https://go.dev/doc/cmd

  3. Go Modules Reference: The official reference for understanding and using Go's dependency management system.

    https://go.dev/ref/mod

  4. gomobile Repository and Wiki: The source code and official documentation for the gomobile tool.

    https://github.com/golang/mobile

  5. GoReleaser Official Documentation: The complete documentation for the GoReleaser tool.

    https://goreleaser.com/

  6. Fyne Developer Documentation: The official documentation and API reference for the Fyne GUI toolkit.

    https://developer.fyne.io/

  7. Wails Official Documentation: The official documentation for the Wails framework. https://wails.io/docs/gettingstarted/installation

  8. Flutter Official Website: The official website for the Flutter framework, for comparison.

    https://flutter.dev/

  9. Kotlin Multiplatform Official Website: The official website for Kotlin Multiplatform, for comparison.

    https://kotlinlang.org/docs/multiplatform-get-started.html

  10. Cobra Library GitHub Repository: The source and documentation for the Cobra CLI library.

    https://github.com/spf13/cobra

  11. Viper Library GitHub Repository: The source and documentation for the Viper configuration library.

    https://github.com/spf13/viper

  12. Android NDK Downloads: The official download page for the Android Native Development Kit required for gomobile. https://developer.android.com/ndk/downloads

  13. Apple's Command Line Tools (including lipo): Information on installing Xcode's command-line tools on macOS. https://developer.apple.com/library/archive/technotes/tn2339/_index.html

Google AI Studio was used in the outlining and research for this article.

You can find it here: https://aistudio.google.com

All images in this article are AI-generated by the author with NightCafe Studio.