documentation/maintaining.md
This document outlines responsibilities and processes for SkiaSharp maintainers.
[!NOTE] This document is still a draft.
Maintaining our fork of Skia and SkiaSharp is usually a straightforward process, but it can get complex when APIs change significantly. Still, it's a rewarding experience - SkiaSharp is one of only two major cross-platform graphics libraries, and it's used by a wide range of developers: from indie app creators to component vendors and full UI framework authors.
Given this variety of users, we’re always careful with how we introduce updates. We want to bring in new features and improvements, while doing our best to avoid breaking existing apps.
Table of Contents
Being a maintainer has some core responsibilities other than updating the bindings. These include issue and PR management.
We do not have a large number of issues being created, but triage is important to spot any regressions or bugs that are impacting customers.
The process of triage is mostly a quick read and apply some labels. There is an engagement score to track to ensure nothing hot rises to the top needing more immediate attention.
[!NOTE] We are in the process of testing out an AI agent to help with triage, labeling and scoring.
There is a workflow that is not actually applying labels yet as we experiment, but can be used to see what labels the AI thinks we need: https://github.com/mono/SkiaSharp/actions/workflows/label-with-ai.yml
There is also another AI workflow to try and calculate an "engagement score" based on comments, reactions and general interactions. This workflow is running now: https://github.com/mono/SkiaSharp/actions/workflows/engagement-scores.yml
The project it writes to is still being evaluated to make sure our weights are good/useful: https://github.com/orgs/mono/projects/1/views/14
Similar to the issues, our PR influx is typically low. There are some fixes and new features from time to time.
Reviewing PRs is mostly making sure the APIs are useful to the general community and do not add any additional burden. However, most changes are smaller fixes or APIs that are useful and long standing.
It is important to make sure that the new code and bugfixes have tests demonstrating the feature. As the upgrades happen, we need to ensure that the feature is covered.
We typically update our fork of Skia and SkiaSharp once or twice a year. This slower cadence helps reduce instability, since the upstream Skia project (from Google) moves quickly and isn’t versioned in the traditional major/minor sense.
Skia operates as a moving target, with monthly "stabilization" branches. Google can (and often does) add, modify, or remove APIs at any time—Skia remains a public project but is still tightly integrated with internal Chromium and Android development.
Because of this, we aim to:
Chromium Release Channels: https://chromiumdash.appspot.com/branches
[!IMPORTANT] Skia calls their versions "milestones".
| Milestone | Channel |
|---|---|
| Latest | Canary |
| Latest-1 | Dev |
| Latest-2 | Beta |
| Latest-3 | Stable |
Updating native Skia is usually manageable, though it can become tricky when there are larger refactors or parallel edits from Google's side.
[!WARNING] Skia does not guarantee API or ABI stability, so breaking changes are expected.
SkPaint into SkPaint and SkFont, required us to redesign the wrapper API to avoid breaking users.Timelines can range from a day for simple merges to a week or two for more involved ones.
Once native Skia is updated, updating SkiaSharp is typically more straightforward. Since we control the .NET API surface, we can mitigate upstream changes more gracefully.
We’re selective about which new native APIs to expose right away. Google iterates quickly, and early-stage APIs may be short-lived or evolve significantly. Lagging slightly behind can actually help — by the time we adopt a new feature, it’s often more stable.
We occasionally wrap a stable, future-looking API form even if the underlying native API is still in flux. This reduces future churn in our .NET surface.
We aim to release updates as previews as early as possible. This allows our community to test changes and catch regressions early.
Some of our core users—including teams like Uno Platform, Avalonia, Telerik, and Syncfusion — are incredibly helpful in providing quick, actionable feedback. A special mention to Nick from DrawnUI, who consistently tests the latest features and pushes performance boundaries.
Since we’re not tied to any specific product cycle, we release when we feel the build is stable and feedback has been positive.
If regressions happen, they’re usually rare and quickly fixable, thanks to our established and reliable dependencies.
Google generally maintains solid compliance, but it’s always good to keep an eye on their DEPS file in native Skia for new dependencies.
We also:
In the rare case that a dependency (e.g., libpng or zlib) introduces a problem, we typically just wait a short time for the fix and update accordingly. These are very rare.