# rust-skia: Safe Rust Bindings for Skia

> rust-skia exposes Skia's C++ graphics API through safe Rust interfaces for desktop, mobile, and WebAssembly targets. It suits Rust applications that need Skia rendering while accepting substantial binary size, build configuration, and platform dependency costs.

**rust-skia/rust-skia** — Rust Bindings for the Skia Graphics Library

- Repository: https://github.com/rust-skia/rust-skia
- Stars: 1,829 · Forks: 198
- Language: Rust
- License: MIT
- Published: 2026-10-16 · Updated: 2026-10-16 · Language: en
- Canonical page: https://hysenlabs.com/projects/rust-skia-rust-skia

## Why rust-skia Exists

rust-skia solves the boundary problem between Rust and Skia, a C++ graphics library. Skia provides the underlying rendering and document capabilities, while its native API does not naturally fit Rust's ownership and type model. This project creates safe Rust bindings to that API so applications can manage Skia objects through Rust-facing types rather than manually crossing a foreign function interface.

The intended audience is Rust developers who need Skia itself, including applications that render vector graphics, images, text, SVG, PDF, or animation-related content. The repository also names Vulkan, Metal, OpenGL, and Direct3D as GPU rendering backends. Target coverage includes Windows, Linux, Android, iOS, and WebAssembly. This is not a general-purpose windowing package. The README points window-rendering users toward the `gl-window` example, but presentation, input, and application lifecycle remain responsibilities for the surrounding Rust application.

The choice is therefore narrower than using a graphics framework written in Rust. It is appropriate when existing requirements already call for Skia, when matching Skia behavior is more important than avoiding native code, or when a Rust codebase needs a controlled binding layer around Skia's C++ implementation.

## Bindings, Features, and Build-Time Data Flow

The repository separates low-level integration from the safe public crate. The top-level Cargo workspace includes `skia-bindings`, `skia-safe`, `skia-org`, `skia-svg-macros`, and `skia-icon`. The published user-facing package is `skia-safe`. This separation lets the build layer deal with native Skia while the safe crate exposes its API.

During a build, `skia-bindings` attempts to obtain matching prebuilt binaries from the `skia-binaries` repository. The build script uses `curl` for this step. Cargo features determine which parts of Skia and its optional facilities are needed, and most feature combinations are documented as having prebuilt coverage. If a target or feature configuration is unavailable, the build script falls back to building Skia and generating the Rust bindings.

The repository tracks the upstream Skia source as a submodule. Its current status identifies the Skia submodule as `chrome/m155`. The workspace metadata records Rust edition 2024 and a minimum Rust version of 1.85. That minimum applies to this repository's workspace configuration; the README's direct installation instruction does not provide a separate consumer toolchain matrix.

Feature selection has practical consequences. The Makefile's documentation builds use combinations including `ganesh`, `gl`, `vulkan`, `metal`, `d3d`, `textlayout`, `svg`, `skottie`, `ureq`, and `webp`. Those entries show what the project considers meaningful optional surface areas, but the README does not claim that every feature is valid on every target. Consumers must inspect the package feature configuration for their chosen target.

## Installing skia-safe and Starting a Window Project

The documented starting point is Cargo's package installer. Run this inside an existing Rust project:

```bash
cargo add skia-safe
```

This adds the `skia-safe` package to that project's dependencies. The README identifies the available package as a prerelease crate on crates.io. It also points to the generated API documentation on docs.rs, which is the relevant place to inspect the safe types and methods for the package version Cargo selected.

For a windowed OpenGL application, the README recommends examining the repository's `gl-window` example. It does not present the example as a command-line executable to install or a complete first program in the root documentation, so no additional invocation can be stated from the available instructions. Based on the repository layout, the example belongs to `skia-safe/examples/gl-window`; it should be read alongside the installed package's API documentation.

A source fallback needs a more substantial toolchain. The build documentation requires LLVM, Python 3, and Ninja. The build script probes both `python` and `python3`, then uses the first that appears to be Python 3. It also expects Ninja in `PATH`. On macOS, the documented Xcode command-line installation is:

```bash
xcode-select --install
```

On Windows, the README calls for Visual Studio 2022 Build Tools with the Desktop Development with C++ workload, Python 3, LLVM, and the MSVC Rust toolchain. Its documented selection command is:

```bash
rustup default stable-msvc
```

On Linux, OpenGL development libraries may be needed for GL builds. X11 builds use the `x11` feature, while Wayland builds use the `wayland` feature and require `libwayland-dev`.

## Prebuilt Binary Constraints Across Targets

The fastest supported route depends on exact target matching. Documented prebuilt targets include `x86_64-pc-windows-msvc`, `aarch64-pc-windows-msvc`, `x86_64-unknown-linux-gnu`, `aarch64-unknown-linux-gnu`, `x86_64-apple-darwin`, `aarch64-apple-darwin`, `aarch64-linux-android`, `x86_64-linux-android`, three listed iOS targets, and `wasm32-unknown-emscripten`.

Linux carries a host-level compatibility boundary. The prebuilt Linux binaries require glibc 2.31 or later and libstdc++ with `GLIBCXX_3.4.28` or later. The README says these versions come from the build container and correspond to at least Ubuntu 20.04, Debian 11, Fedora 32, and CentOS Stream 9. It also states that `build.rs` does not detect an incompatible host automatically. On an older Linux system, the downloaded binary can fail while linking.

The documented way to request a source build is:

The README also says the `binary-cache` feature can be disabled to build from source. This environment variable is not a general feature selector. It changes how the build obtains Skia, which matters because a source build requires the full native toolchain and substantially more build work.

Architecture is another boundary. Having a supported operating system does not guarantee a binary for every architecture. Android, iOS, Windows, macOS, Linux, and WebAssembly each have explicit target names, and a build configuration outside that table may proceed through the source-build path. The documentation does not promise that every native toolchain can compile every listed target.

## Skia Bindings Versus a Rust-Native Graphics Stack

The main alternative is a Rust-native graphics stack rather than another Skia binding. The practical difference is architectural: rust-skia retains Skia's C++ codebase and exposes it through generated and handwritten Rust interfaces, while a Rust-native stack keeps more of its implementation and API surface inside the Rust ecosystem. The repository does not identify a particular Rust-native competitor, so naming one would add an unsupported comparison.

Choose rust-skia when matching Skia capabilities is the requirement. Its repository explicitly covers familiar Skia domains and backend names, including graphics, text layout, SVG, PDF-related subject matter, and GPU APIs. A project that already depends on Skia concepts or needs several of those facilities through one native library has a concrete reason to accept the binding architecture.

Choose a Rust-native alternative when avoiding C++, large native builds, or platform-specific toolchains is more important than using Skia. That does not guarantee universal portability: graphics libraries can still have system driver and backend requirements. The difference is that rust-skia specifically brings the build and deployment weight of Skia and its C++ interface, even though Rust supplies safe access.

The project is also the wrong choice for a small crate that only needs to place a few primitives on a native application surface. The README's first concrete integration example already concerns an OpenGL window, and the source build requires multiple external tools. Without a specific need for Skia, that dependency footprint may exceed the value delivered.

## Maintenance, Releases, and MIT Upgrade Surface

The repository is not archived, and its last push was on 2026-10-10. Recent published releases include 0.153.3 on 2026-09-04 and 0.153.2 on 2026-09-03, alongside release 0.99.0 on 2026-06-19. These dates show recent repository activity and package releases, but the README's statement that it provides up-to-date bindings is a project claim rather than an independent compatibility guarantee.

Upgrades can involve more than a normal small Rust crate. The public API is backed by a tracked Skia submodule, generated bindings, native binaries, optional features, and platform toolchains. A version change can therefore affect source compatibility, available binary artifacts, and the feature set required for rendering. The justfile also includes release verification for release commits, workflow assets, binary downloads, source builds, and generated images, which indicates that release consistency spans several artifacts.

The repository license is MIT. That permits reuse and modification under the license's conditions, including preservation of its copyright and permission notice. This is a statement about the declared license, not legal advice. Consumers still need to account for their own distribution policies and any separately applicable dependencies when packaging a binary.

The main upgrade cost is therefore build reproducibility. Before accepting a new release, teams should compare the required features and targets against the documented prebuilt matrix. On Linux, they should also check glibc and libstdc++ versions. On an unusual target, they should be prepared for the documented LLVM, Python 3, and Ninja requirements.

## Conclusion

Adopt rust-skia when a Rust application specifically needs Skia's rendering, text, image, SVG, PDF, or GPU backends and its release targets match the available prebuilt binaries. Do not choose it solely to avoid native graphics dependencies, since Skia remains a large C++ dependency and may require LLVM, Python 3, Ninja, and platform build tools. Verify target support, host runtime requirements, enabled Cargo features, and the intended Skia release alignment before integration. For the documented `aarch64-linux-android` path, first confirm that your Android build environment can link the downloaded Skia binary.

## FAQ

### How do I add rust-skia to a Rust project?

Run `cargo add skia-safe` in the project directory. The README identifies `skia-safe` as the safe binding crate published through crates.io.

### Which platforms have prebuilt Skia binaries?

The README lists supported Windows, Linux, macOS, Android, iOS, and WebAssembly targets. Availability depends on the exact target and selected feature configuration, not only the operating system.

### What happens when rust-skia cannot use a prebuilt binary?

The build script attempts to build Skia from source and generate the Rust bindings. That path requires LLVM, Python 3, and Ninja, with additional platform tooling documented for macOS, Windows, and Linux.

## Sources

- [Issues](https://github.com/rust-skia/rust-skia/issues)
- [License: MIT](https://github.com/rust-skia/rust-skia/blob/master/LICENSE)
- [README](https://github.com/rust-skia/rust-skia/blob/master/README.md)
- [Releases](https://github.com/rust-skia/rust-skia/releases)
- [rust-skia/rust-skia on GitHub](https://github.com/rust-skia/rust-skia)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/rust-skia-rust-skia
