28 releases (16 breaking)

0.34.0 Sep 11, 2020
0.32.1 Aug 24, 2020
0.30.1 Jul 28, 2020
0.27.1 Mar 19, 2020
0.19.0 Nov 11, 2019

#9 in Graphics APIs

Download history 248/week @ 2020-06-01 179/week @ 2020-06-08 154/week @ 2020-06-15 268/week @ 2020-06-22 355/week @ 2020-06-29 278/week @ 2020-07-06 203/week @ 2020-07-13 199/week @ 2020-07-20 232/week @ 2020-07-27 252/week @ 2020-08-03 244/week @ 2020-08-10 234/week @ 2020-08-17 495/week @ 2020-08-24 356/week @ 2020-08-31 498/week @ 2020-09-07 268/week @ 2020-09-14

1,182 downloads per month
Used in 7 crates (2 directly)

MIT license

26K SLoC

Rust 23K SLoC // 0.0% comments C++ 3K SLoC // 0.1% comments

Safe Rust bindings to the Skia Graphics Library.

This packages contains safe Rust wrappers for Skia and uses skia-bindings to build and interface with the Skia C++ library.

For information about the supported build targets and how to run the examples, please visit the github page of the rust-skia project.


Function level documentation is not yet available. To get started, take a look at the Rust examples or the Skia documentation.

Bindings & Wrappers

Skia-safe wraps most parts of the public Skia C++ APIs:

  • Vector Geometry: Matrix, Rect, Point, Size, etc.
  • Most drawing related classes and functions: Surface, Canvas, Paint, Path.
  • Effects and Shaders.
  • Utility classes we think are useful.
  • PDF & SVG rendering
  • Skia Modules
  • GPU Backends
    • Vulkan
    • OpenGL
    • Metal
    • Direct3D
    • WebGPU Dawn

Wrappers for functions that take callbacks and virtual classes are not supported right now. While we think they should be wrapped, the use cases related seem to be rather special, so we postponed that for now.


Skia-safe supports the following features that can be configured via cargo:


Platform support for OpenGL or OpenGL ES can be enabled by adding the feature gl. Since version 0.25.0, rust-skia is configured by default to enable CPU rendering only. Before that, OpenGL support was included in every feature configuration. To render the examples with OpenGL, use

(cd skia-org && cargo run --features gl [OUTPUT_DIR] --driver opengl)


Vulkan support can be enabled by adding the feature vulkan. To render the examples with Vulkan, use

(cd skia-org && cargo run --features vulkan [OUTPUT_DIR] --driver vulkan)

Note that Vulkan drivers need to be available. On Windows, they are most likely available already, on Linux this article on linuxconfig.org might get you started, and on macOS with Metal support, install the Vulkan SDK for Mac and configure MoltenVK by setting the DYLD_LIBRARY_PATH, VK_LAYER_PATH, and VK_ICD_FILENAMES environment variables as described in Documentation/getting_started_macos.html.


Support for Metal on macOS and iOS targets can be enabled by adding the feature metal.


The Direct3D backend can be enabled for Windows targets by adding the feature d3d.


The Cargo feature textlayout enables text shaping with Harfbuzz and ICU by providing bindings to the Skia modules skshaper and skparagraph.

The skshaper module can be accessed through skia_safe::Shaper and the Rust bindings for skparagraph are in the skia_safe::textlayout module.

On Windows, the file icudtl.dat must be available in your executable's directory. To provide the data file, either copy it from the build's output directory (shown when skia-bindings is compiled with cargo build -vv | grep "ninja: Entering directory"), or - if your executable directory is writable - invoke the function skia_safe::icu::init() before using the skia_safe::Shaper object or the skia_safe::textlayout module.

Simple examples of the skshaper and skparagraph module bindings can be found in the skia-org example command line application.


Conflicting with Rust philosophy, we've decided to fully support Skia's reference counting semantics, which means that all reference counted types can be cloned and modified from within the same thread. To send a reference counted type to another thread, its reference count must be 1, and must be wrapped with the Sendable type and then unwrapped in the receiving thread. The following functions support the sending mechanism:

Every mutable reference counted type implements the following two functions:

can_send(&self) -> bool

returns true if the handle can be sent to another thread right now.

wrap_send(self) -> Result<Sendable<Self>, Self>

wraps the handle into a Sendable type that implements Send.

And the Sendable type implements:


which unwraps the original handle.

For more information about the various wrapper types, take a look at the rust-skia wiki.


~58K SLoC