This document outlines the platform-specific integration strategy for GoFlow, following Flutter's approach of native platform projects that host the framework code.
Currently, platform directories contain simple Go runners:
macos/
└── main.go # Basic Go file that calls lib.Run()
This works for initial development but doesn't provide:
- Proper native app bundles
- Platform-specific UI integration (menus, dock icons, etc.)
- Code signing and distribution
- Platform features (notifications, file associations, etc.)
Following Flutter's model, each platform directory should contain a full native project:
macos/
├── Runner.xcodeproj/ # Xcode project
├── Runner/
│ ├── AppDelegate.swift # macOS app entry point
│ ├── MainViewController.swift # Window controller
│ ├── Info.plist # App metadata
│ ├── Assets.xcassets/ # App icon, etc.
│ └── Runner-Bridging-Header.h
├── RunnerTests/
├── build.sh # Script to build Go code
└── embed_go.sh # Script to embed Go binary
How it works:
- Xcode project creates native macOS app (.app bundle)
- Build phase compiles Go code from
../lib/to shared library or binary - AppDelegate initializes GLFW/WGPU rendering context
- MainViewController loads and executes Go code
- Go code uses GLFW for window management, WGPU for rendering
- Result: Proper macOS app with dock icon, menus, etc.
windows/
├── Runner.sln # Visual Studio solution
├── Runner/
│ ├── Runner.vcxproj # Project file
│ ├── main.cpp # Win32 entry point
│ ├── Resource.rc # Resources (icon, manifest)
│ └── app.manifest # Windows manifest
├── build.bat # Script to build Go code
└── embed_go.bat # Script to embed Go DLL
How it works:
- Visual Studio project creates Windows .exe
- Build script compiles Go code to DLL
- Win32 app initializes window and rendering context
- Loads and calls into Go DLL
- Result: Windows executable with proper icon, manifest, etc.
linux/
├── CMakeLists.txt # CMake build configuration
├── main.cc # C++ entry point
├── Makefile # Alternative: simple Makefile
├── runner.desktop # Linux desktop entry
├── icons/ # App icons (various sizes)
└── build.sh # Build script
How it works:
- CMake/Make builds native launcher
- Compiles Go code to shared library
- Launcher initializes X11/Wayland window
- Loads Go shared library
- Result: Linux app with desktop integration
Before native platform projects, we need the rendering layer:
-
GLFW Bindings
- Use
github.com/go-gl/glfwfor cross-platform windowing - Create window, handle events
- Provide OpenGL/Vulkan context
- Use
-
WGPU Bindings
- Use WebGPU bindings for Go (or cgo to wgpu-native)
- Abstract rendering backend
- Support Metal (macOS), DirectX (Windows), Vulkan (Linux/Windows)
-
Update Platform Runners
- Initialize GLFW window
- Create WGPU rendering context
- Set up event loop
- Call into lib code for rendering
Once GLFW+WGPU work, add native projects:
- Create Xcode project template
- Add Swift/Objective-C code to:
- Create NSWindow
- Initialize Metal layer for WGPU
- Handle app lifecycle (menus, dock, etc.)
- Load and execute Go code
- Add build scripts to compile Go code
- Support code signing and notarization
- Create VS project template
- Add C++ code to:
- Create Win32 window
- Initialize DirectX context for WGPU
- Handle Windows messages
- Load Go DLL
- Add build scripts
- Support manifest and code signing
- Create CMake template
- Add C++ code to:
- Create X11/Wayland window
- Initialize Vulkan context
- Handle events
- Load Go shared library
- Create .desktop file for integration
- Support AppImage/Flatpak/Snap packaging
Update goflow create to generate native projects:
// In createPlatformRunner()
switch platform {
case "macos":
createXcodeProject(projectPath, modulePath)
case "windows":
createVisualStudioProject(projectPath, modulePath)
case "linux":
createCMakeProject(projectPath, modulePath)
}Once basic integration works, add platform-specific features:
- macOS: Menu bar, dock, notifications, app sandbox
- Windows: System tray, toast notifications, UAC
- Linux: DBus, notifications, desktop themes
import Cocoa
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
var window: NSWindow!
var goLibrary: UnsafeMutableRawPointer?
func applicationDidFinishLaunching(_ aNotification: Notification) {
// 1. Create window
window = NSWindow(
contentRect: NSRect(x: 0, y: 0, width: 800, height: 600),
styleMask: [.titled, .closable, .miniaturizable, .resizable],
backing: .buffered,
defer: false
)
window.center()
window.makeKeyAndOrderFront(nil)
// 2. Initialize Metal for WGPU
let metalLayer = CAMetalLayer()
window.contentView?.layer = metalLayer
window.contentView?.wantsLayer = true
// 3. Load Go code
guard let libPath = Bundle.main.path(forResource: "goflow", ofType: "dylib") else {
fatalError("GoFlow library not found")
}
goLibrary = dlopen(libPath, RTLD_NOW)
guard goLibrary != nil else {
fatalError("Failed to load GoFlow library: \(String(cString: dlerror()))")
}
// 4. Get and call Run function
typealias RunFunc = @convention(c) () -> Void
guard let runSymbol = dlsym(goLibrary, "Run"),
let run = unsafeBitCast(runSymbol, to: RunFunc?.self) else {
fatalError("Run function not found")
}
// 5. Execute Go application
run()
}
func applicationWillTerminate(_ aNotification: Notification) {
if let lib = goLibrary {
dlclose(lib)
}
}
}cd macos
go run main.go# macOS
cd macos
xcodebuild -project Runner.xcodeproj -scheme Runner
open build/Release/MyApp.app
# Windows
cd windows
MSBuild Runner.sln /p:Configuration=Release
start bin/Release/MyApp.exe
# Linux
cd linux
cmake . && make
./build/myapp- Create .app bundle
- Code sign with Developer ID
- Notarize with Apple
- Distribute as DMG or via Mac App Store
- Create installer (NSIS, WiX, or Inno Setup)
- Code sign with certificate
- Distribute as .exe or via Microsoft Store
- Create AppImage (self-contained)
- Create Flatpak (Flathub)
- Create Snap (Snapcraft)
- Distribute via package managers
- Proper App Bundles: Real .app, .exe with icons and metadata
- Platform Integration: Menus, dock, system tray, etc.
- Distribution Ready: Can be signed and distributed properly
- Performance: Native event loop and rendering context
- Developer Experience: Use Xcode/VS for platform-specific debugging
- Familiar Model: Follows Flutter's proven approach
- ✅ Create CLI tool with basic structure
- ✅ Design platform integration architecture
- ⏳ Implement GLFW + WGPU integration in Go
- ⏳ Create Xcode project template for macOS
- ⏳ Create Visual Studio template for Windows
- ⏳ Create CMake template for Linux
- ⏳ Update CLI to generate native projects
- ⏳ Add build scripts and automation
- ⏳ Document platform-specific features
- ⏳ Support code signing and distribution
- Flutter Platform Channels
- Flutter Desktop Embedding
- GLFW Documentation
- WGPU Native
- Go Mobile - Reference for Go-native binding patterns