Two months ago, SkiaSharp 4.0 Preview 1 landed with an enormous Skia engine jump, variable font support, and immutable SKPath. It was promising, but preview means preview — nobody was shipping it to production. On 29 June 2026, the team released SkiaSharp 4.148.0, the first stable v4 build. The version number tells you the engine version: Skia milestone 148, one bump beyond Preview 1's m147, synced with Chrome's stable channel.

This is the release you can actually depend on. Beyond the features already covered in the preview, stable brings concrete GPU performance numbers, animated WebP encoding, a final sweep that turns every remaining deprecated API into a compile error, and lifecycle fixes that eliminate an entire class of use-after-free crashes. If SkiaSharp is in your dependency graph, upgrading is now a straightforward decision rather than a calculated risk.

The performance story, with actual numbers

Preview 1 promised "faster rendering" without publishing benchmarks. Stable delivers the receipts. The measurements come from an OpenGL GPU backend on Windows 11 with .NET 10, targeting the UI workloads that dominate real apps:

Scenario v3 (FPS) v4.148.0 (FPS) Improvement
Dashboard with shadowed cards 65 80 ~24%
Scrolling activity feed 47 58 ~23%

These are not cherry-picked micro-benchmarks. Shadowed cards and scrolling lists are the bread and butter of MAUI, Uno Platform, and Avalonia UIs. A 24% jump means the difference between occasional jank and consistently smooth 60+ FPS on mid-range hardware.

On the CPU side, procedural Perlin-noise shaders run approximately six times faster. If you use noise-based backgrounds, procedural textures, or generative art effects, this is a dramatic improvement for free.

Charts, text rendering, and vector maps show no regressions — the team explicitly validated that the engine upgrade does not trade one workload for another.

// TIP

If you maintain a custom SKGLView control in MAUI, benchmark your specific rendering loop before and after. The 24% figure is representative, but your mileage depends on how much of your frame time is GPU-bound versus layout-bound.

Animated WebP encoding with SKWebpEncoder

SkiaSharp could always decode animated WebP files, but encoding them required dropping down to native interop or using a separate library. Version 4.148.0 introduces SKWebpEncoder with first-class animated encoding support.

The API follows a frame-based model: you build an array of SKWebpEncoderFrame instances, each wrapping an SKPixmap and a duration, then encode them in one call.

Services/AnimatedWebpExporter.cs
public static SKData CreateAnimation(
    IReadOnlyList<SKBitmap> frames,
    TimeSpan frameDuration,
    float quality = 80f)
{
    var webpFrames = new SKWebpEncoderFrame[frames.Count];

    for (int i = 0; i < frames.Count; i++)
    {
        webpFrames[i] = new SKWebpEncoderFrame(
            frames[i].PeekPixels(),
            frameDuration);
    }

    var options = new SKWebpEncoderOptions(
        SKWebpEncoderCompression.Lossy,
        quality);

    return SKWebpEncoder.EncodeAnimated(webpFrames, options)
        ?? throw new InvalidOperationException(
            "WebP encoding failed — check that all frames share the same dimensions.");
}

Each SKWebpEncoderFrame takes an SKPixmap and a TimeSpan for the frame delay. The SKWebpEncoderOptions struct controls compression mode (lossy or lossless) and quality. EncodeAnimated returns SKData containing the complete animated WebP file, or null if encoding fails.

A practical use case: generating loading spinners, animated thumbnails, or short UI recordings entirely on the server without shelling out to FFmpeg or ImageMagick.

Controllers/AnimationController.cs
[HttpGet("preview.webp")]
public IActionResult GetAnimatedPreview()
{
    var frames = RenderPreviewFrames(frameCount: 30);
    using var data = AnimatedWebpExporter.CreateAnimation(
        frames,
        frameDuration: TimeSpan.FromMilliseconds(33),
        quality: 75f);

    return File(data.ToArray(), "image/webp");
}

// WARNING

SKWebpEncoder.EncodeAnimated buffers all frames in memory simultaneously. For long animations or high-resolution frames, consider encoding in batches or streaming individual frames to disk first.

The legacy API cleanup: deprecated becomes deleted

Preview 1 marked legacy APIs as obsolete with warnings. Stable promotes those warnings to compile errors. If you were suppressing the warnings and planning to deal with them later, "later" has arrived.

The biggest category of breakage is the old SKPaint-based text API. In SkiaSharp v3, font properties like TextSize, Typeface, and TextEncoding lived on SKPaint. In v4, they moved to SKFont — a dedicated type that separates font configuration from paint styling. The v3 members were deprecated in Preview 1 and are now removed from the reference assembly entirely.

Example.cs
// Bad — no longer compiles in v4.148.0
var paint = new SKPaint();
paint.TextSize = 24;          // compile error
paint.Typeface = typeface;     // compile error
canvas.DrawText("Hello", 0, 0, paint);

// Good — use SKFont for text properties
using var font = new SKFont(typeface, size: 24);
using var paint = new SKPaint();
canvas.DrawText("Hello", 0, 0, font, paint);

The same applies to SKPath mutation methods. MoveTo, LineTo, AddRect, and roughly 30 other methods have moved to SKPathBuilder:

Example.cs
// Bad — mutable path methods are gone
var path = new SKPath();
path.MoveTo(0, 0);
path.LineTo(100, 50);
path.LineTo(50, 100);
path.Close();

// Good — build, then detach an immutable path
using var builder = new SKPathBuilder();
builder.MoveTo(0, 0);
builder.LineTo(100, 50);
builder.LineTo(50, 100);
builder.Close();
using var path = builder.Detach();

Obsolete enum members have also been removed from the reference assembly, so code using old SKFilterQuality values or similar deprecated enums will fail at compile time.

// TIP

A green build on 4.148.0 means your entire SkiaSharp surface is v4-clean. A red build gives you a finite list of mechanical replacements — there are no behavioural changes hiding behind the compile errors.

Lifecycle fixes: no more use-after-free crashes

The most important stability improvement in 4.148.0 is not a new feature — it is a redesign of how native singleton objects are managed. In v3 and the previews, shared native objects like default SKPaint instances and font managers used a simple disposable pattern. If the garbage collector ran at the wrong moment and finalized a singleton before other objects that referenced it, you got a use-after-free crash — intermittent, hard to reproduce, and nearly impossible to diagnose.

Stable introduces proper reference counting for native singletons. The native object stays alive as long as any managed wrapper holds a reference. This eliminates an entire category of crashes that manifested as random AccessViolationException or SIGSEGV on Mono/NativeAOT.

Two specific bug fixes in the same area:

// IMPORTANT

If you have been seeing sporadic AccessViolationException crashes in production with SkiaSharp v3, particularly under load or after extended runtime, upgrade to 4.148.0 before investigating further. The lifecycle fixes alone may resolve your issue.

Platform and dependency updates

Stable ships updated native dependencies across the board:

Dependency Version
HarfBuzz 14.2.0
libexpat 2.8.1
libjpeg-turbo 3.1.4.1
FreeType 2.14.3
zlib 1.3.2.1
libpng 1.6.58

New platform support includes Linux Bionic native assets and Tizen x64/ARM64 builds. On the other end, pre-.NET 8 Emscripten WASM builds have been discontinued — if you target Blazor WASM, you need .NET 8 or later.

The Android SKGLView rendering bug after MAUI tab switching has been fixed, as has the WinUI projection DLL resolution issue for .NET 9 consumers. If either of those cost you debugging hours, the upgrade pays for itself immediately.

Migrating from v3 to v4.148.0

The migration path is deliberately mechanical. There are no subtle behavioural changes lurking behind the API removals — every compile error has a direct replacement.

Step 1: Update the package reference.

MyApp.csproj
<ItemGroup>
    <PackageReference Include="SkiaSharp" Version="4.148.0" />
    <PackageReference Include="SkiaSharp.Views.Maui.Controls" Version="4.148.0" />
</ItemGroup>

For Uno Platform projects, use the MSBuild property instead:

MyApp.csproj
<PropertyGroup>
    <SkiaSharpVersion>4.148.0</SkiaSharpVersion>
</PropertyGroup>

Step 2: Fix compile errors. Work through the list — most fall into three categories:

  1. SKPaint text members — move to SKFont
  2. SKPath mutation methods — move to SKPathBuilder
  3. Obsolete enums — replace with current equivalents (e.g. SKSamplingOptions instead of SKFilterQuality)

Step 3: Search for manual Exif rotation. The engine now respects Exif orientation metadata automatically. If you have code that reads Exif tags and rotates bitmaps, it will now double-rotate. Remove the manual rotation.

Step 4: Test your rendering. The engine bump from m133 (v3) through m147 (Preview 1) to m148 (stable) changes rendering behaviour subtly — mipmap sharpening is on by default, colour transfer functions are corrected. These are improvements, but if you have pixel-perfect snapshot tests, they will need updating.

What is next: Graphite and the 4.150.0 preview

The team has already shipped 4.150.0 RC 1, and it includes the feature that matters most for the future of SkiaSharp rendering: Graphite, the next-generation GPU backend being developed by Uno Platform.

Graphite replaces the aging Ganesh GPU backend that has powered Skia's hardware acceleration for over a decade. It is designed for modern graphics APIs — Vulkan, Metal, and Direct3D 12 — with a cleaner abstraction layer and better parallelism. When Graphite lands in a stable release, GPU-bound workloads should see another significant jump.

The 4.150.0 preview also adds new image and colour filter APIs, SkSL image filters for custom GPU shader effects, and optimised SKSurface.Canvas caching. If you are already comfortable running on the v4 stable branch, the preview channel is worth watching.

SkiaSharp now follows a predictable release cadence aligned with Chrome's release channels:

This means no more multi-year gaps between Skia engine updates. Every Chrome stable milestone brings an updated SkiaSharp stable build.

Common pitfalls

Summary