Shaft is a cross-platform UI framework designed for high-performance applications with a focus on simplicity and customizability.
New✨: A blog post introducing Shaft in details has been posted here.
-
MacOS: Shaft requires Xcode to be installed. After installing Xcode, if you encounter errors like
xcrun: error: unable to lookup item...
, try update your command line tools following these instructions. -
Linux:
- Install Swift from the official guide
- Install SDL backend dependencies from the official documentation. For Ubuntu 24.04, run:
sudo apt install ninja-build pkg-config libasound2-dev libpulse-dev libaudio-dev libjack-dev libsndio-dev libusb-1.0-0-dev libx11-dev libxext-dev libxrandr-dev libxcursor-dev libxfixes-dev libxi-dev libxss-dev libwayland-dev libxkbcommon-dev libdrm-dev libgbm-dev libgl1-mesa-dev libgles2-mesa-dev libegl1-mesa-dev libdbus-1-dev libibus-1.0-dev libudev-dev fcitx-libs-dev libunwind-dev libpipewire-0.3-dev libdecor-0-dev libfontconfig-dev
-
Windows: Install Swift following the official guide shoube be enough. However, the stable release of Swift for Windows have a few issues that may prevent Shaft from running. It's highly recommended to use development snapshots instead. You can find the latest snapshot here.
git clone https://github.com/ShaftUI/Shaft.git
cd Shaft
swift package plugin setup-skia
swift run Playground
These commands will launch the built-in Playground application, which serves as both an interactive demonstration and comprehensive documentation for the Shaft framework.
The
setup-skia
command downloads prebuilt Skia binaries to the./.shaft
directory for the package to use. In the future we may get rid of this when swift-package-manager#7035 has made progress.
To create a new project with Shaft, the CounterTemplate is a good starting point.
- Simple & Hackable
No build infrastructure or special toolchain required - just a regular Swift package containing both engine and framework, makes it easy to customize, extend, and adapt to your specific needs.
- Built for demanding workloads
Built for demanding workloads with native multi-threading support, direct low-level graphics API access, and deterministic memory management through ARC. Scales effortlessly from simple apps to complex, resource-intensive applications.
- Modular design
Shaft's modular design enables integration of custom backends and renderers without much effort. This flexibility allows for unique use cases like terminal-based UI or creating Wayland compositors, enabling developers to adapt the framework for specialized use cases.
- Automatic UI-data synchronization
Data marked with @Observable
enables automatic UI updates when values change. The framework automatically tracks these objects and efficiently refreshes only the affected UI components, eliminating the need for manual state management and reducing boilerplate code. This reactive approach ensures your UI stays synchronized with your data in a performant way:
@Observable class Counter {
var count = 0
}
let counter = Counter()
class CounterView: StatelessWidget {
func build(context: any BuildContext) -> any Widget {
Column {
Text("Count: \(counter.count)")
Button {
counter.count += 1
} child: {
Text("Increment")
}
}
}
}
- Shaft Framework: Basicly a port of Flutter's framework part to Swift with minor changes. Most of Flutter's concepts should be applicable.
- Shaft.Backend: An protocol that provides everything that the framework requires to run, such as event loop, text input, etc. It's a layer that abstracts the platform specific code.
- Shaft.Renderer: An protocol that abstracts the underlying graphics API, such as Skia or CoreGraphics.
- ShaftKit: The built-in customizable widget toolkit that provides high-level widgets for rapid application development.
- ShaftApp: The application that developer writes.
More documentation can be found in the Playground app.