mono/SkiaSharp
SkiaSharp is a cross-platform 2D graphics API for .NET platforms based on Google's Skia Graphics Library. It provides a comprehensive 2D API that can be used across mobile, server and desktop models to render images.
Healthy across all four use cases
Permissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit today
- ✓7 active contributors
- ✓MIT licensed
Show 3 more →Show less
- ✓CI configured
- ⚠Concentrated ownership — top contributor handles 77% of recent commits
- ⚠No test directory detected
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/mono/skiasharp)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/mono/skiasharp on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: mono/SkiaSharp
Generated by RepoPilot · 2026-05-10 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/mono/SkiaSharp shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across all four use cases
- Last commit today
- 7 active contributors
- MIT licensed
- CI configured
- ⚠ Concentrated ownership — top contributor handles 77% of recent commits
- ⚠ No test directory detected
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live mono/SkiaSharp
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/mono/SkiaSharp.
What it runs against: a local clone of mono/SkiaSharp — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in mono/SkiaSharp | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch main exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 30 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of mono/SkiaSharp. If you don't
# have one yet, run these first:
#
# git clone https://github.com/mono/SkiaSharp.git
# cd SkiaSharp
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of mono/SkiaSharp and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "mono/SkiaSharp(\\.git)?\\b" \\
&& ok "origin remote is mono/SkiaSharp" \\
|| miss "origin remote is not mono/SkiaSharp (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
&& ok "license is MIT" \\
|| miss "license drift — was MIT at generation time"
# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
&& ok "default branch main exists" \\
|| miss "default branch main no longer exists"
# 4. Critical files exist
test -f ".agents/skills/issue-triage/SKILL.md" \\
&& ok ".agents/skills/issue-triage/SKILL.md" \\
|| miss "missing critical file: .agents/skills/issue-triage/SKILL.md"
test -f ".agents/skills/issue-fix/SKILL.md" \\
&& ok ".agents/skills/issue-fix/SKILL.md" \\
|| miss "missing critical file: .agents/skills/issue-fix/SKILL.md"
test -f ".agents/skills/review-skia-update/SKILL.md" \\
&& ok ".agents/skills/review-skia-update/SKILL.md" \\
|| miss "missing critical file: .agents/skills/review-skia-update/SKILL.md"
test -f ".agents/skills/api-add-review/references/api-design-rules.md" \\
&& ok ".agents/skills/api-add-review/references/api-design-rules.md" \\
|| miss "missing critical file: .agents/skills/api-add-review/references/api-design-rules.md"
test -f ".agents/skills/pr-commit-message/references/pryor-style-guide.md" \\
&& ok ".agents/skills/pr-commit-message/references/pryor-style-guide.md" \\
|| miss "missing critical file: .agents/skills/pr-commit-message/references/pryor-style-guide.md"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 30 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~0d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/mono/SkiaSharp"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
SkiaSharp is a .NET binding to Google's Skia graphics library that provides cross-platform 2D vector graphics rendering for .NET 6+, .NET Standard 2.0, .NET Framework, and emerging platforms like WASM and Uno. It enables developers to draw shapes, text, images, and complex graphics with hardware acceleration across desktop (Windows/macOS/Linux), mobile (iOS/Android/tvOS), and web (WASM/Blazor) from a single C# codebase. Monorepo structure with bindings layer (C# P/Invoke to native Skia), view integration packages (SkiaSharp.Views.Maui.Controls, SkiaSharp.Views.Uno.WinUI), and agentic automation workflows in .agents/ for issue triage, repro, and API design review. Core API surface lives in C# with platform-specific implementations in SkiaSharp.Views.* namespaces.
👥Who it's for
.NET developers building cross-platform applications needing native 2D graphics—game engines, data visualization tools, design applications, image editors, and UI frameworks like MAUI and WinUI 3 that require pixel-perfect rendering without platform-specific code.
🌱Maturity & risk
Production-ready and actively maintained. The project has dual CI pipelines (Azure DevOps private + public), organized skill-based agent workflows for triage/fix/repro, and multiple published NuGet packages (SkiaSharp, HarfBuzzSharp, SkiaSharp.Views variants). Large C# codebase (3.7M lines) with established APIs documented on docs.microsoft.com indicates stability and broad adoption.
Core binding stability is low-risk due to Microsoft backing and mature Skia upstream. Medium-risk: platform support matrix is broad (10+ platforms listed) creating maintenance burden; native binary distribution strategy (separate SkiaSharp.NativeAssets.Linux packages) adds complexity. The .agents/ workflow automation suggests active community/issue management, but single-library dependency on Google's Skia binary releases means upstream breaking changes cascade downstream.
Active areas of work
Active agentic workflow integration: .agents/ contains structured skills for issue-fix, issue-repro, issue-triage, and api-add-review with validation scripts, eval datasets, and comprehensive reference guides. Focus on automating common processes (PR templates, fix schema validation, platform-specific repro instructions) suggests scaling team efficiency rather than major API expansion.
🚀Get running
git clone https://github.com/mono/SkiaSharp.git
cd SkiaSharp
# For building, requires .NET SDK 6.0+
dotnet restore
dotnet build
# View agentic workflows and skills
cat .agents/agents/agentic-workflows.agent.md
Daily commands:
# Build all targets
dotnet build -c Release
# Run tests (if present in solution)
dotnet test
# Pack NuGet
dotnet pack -c Release
# For specific platform (example Android with .NET workload)
dotnet build -f net6.0-android
🗺️Map of the codebase
.agents/skills/issue-triage/SKILL.md— Defines the triage workflow that classifies issues—essential for understanding how issues flow through the repo's automated systems..agents/skills/issue-fix/SKILL.md— Core skill definition for fixing issues; contributors must understand the fix validation schema and workflow before submitting PRs..agents/skills/review-skia-update/SKILL.md— Documents the Skia native dependency update process—critical for maintaining the underlying graphics library integration..agents/skills/api-add-review/references/api-design-rules.md— Establishes API design rules that all public-facing additions must follow; non-negotiable for API consistency..agents/skills/pr-commit-message/references/pryor-style-guide.md— Defines commit message conventions used across the project; every contributor must follow this for consistent history..agents/skills/native-dependency-update/references/breaking-changes.md— Catalogs breaking changes in native Skia updates; essential context for version planning and compatibility decisions..agents/skills/issue-repro/SKILL.md— Specifies reproduction case requirements and validation; understanding this is mandatory before opening or closing issues.
🛠️How to make changes
Add a new issue triage category
- Add the new category name and description to the labels taxonomy (
.agents/skills/issue-triage/references/labels.md) - Update the triage schema JSON to include decision rules for the new category (
.agents/skills/issue-triage/references/triage-schema.json) - Add example triage outputs demonstrating the new category (
.agents/skills/issue-triage/references/triage-examples.md) - Update the triage validator to recognize the new category (
.agents/skills/issue-triage/scripts/validate-triage.py)
Add a new API to SkiaSharp
- Review the mandatory design rules before proposing the API (
.agents/skills/api-add-review/references/api-design-rules.md) - Add the API definition to the workflow and submit for review (
.agents/skills/api-add-review/SKILL.md) - Ensure API documentation follows established patterns (
.agents/skills/api-docs/references/patterns.md) - Validate the API checklist is complete before merging (
.agents/skills/api-docs/references/checklist.md)
Update Skia native library binding
- Document any breaking changes introduced by the update (
.agents/skills/native-dependency-update/references/breaking-changes.md) - Run the Skia update review script to validate C# bindings (
.agents/skills/review-skia-update/scripts/run_review.py) - Check generated files are correctly updated (
.agents/skills/review-skia-update/scripts/check_generated_files.py) - Document the update and breaking changes in the review summary (
.agents/skills/review-skia-update/references/writing-summaries.md)
Submit a fix for an issue
- Follow commit message style guide for all commits in the fix (
.agents/skills/pr-commit-message/references/pryor-style-guide.md) - Ensure fix submission conforms to the fix schema (
.agents/skills/issue-fix/references/fix-schema.json) - Run the fix validator locally before submitting PR (
.agents/skills/issue-fix/scripts/validate-fix.py) - Reference reproducible test cases if applicable (
.agents/skills/issue-repro/references/repro-schema.json)
🔧Why these technologies
- LLM-based agents (Agentic Workflows) — Automate high-volume issue classification, reproduction validation, and code review without manual intervention; scales with incoming issue volume
- JSON Schema (fix-schema.json, repro-schema.json, triage-schema.json) — Provides machine-readable contracts for validation across Python/PowerShell scripts; enables automated enforcement of quality gates
- Python + PowerShell scripts — Cross-platform validation pipelines for CI/CD integration; Python for complex schema validation, PowerShell for Windows-native workflows
- Markdown documentation + Jinja2 templating — Human-readable guidelines co-located with schemas; templates generate reports with consistent formatting for release notes and triage summaries
- .NET / C# binding generation — Wraps Google's Skia graphics engine for .NET; Skia provides cross-platform 2D rendering, C# bindings make it accessible to managed code
🪤Traps & gotchas
Platform binary distribution: SkiaSharp.NativeAssets.Linux requires separate package installation per distro—building without explicit asset package can fail silently. P/Invoke marshaling: Changes to SKSurface/SKCanvas method signatures may require adjusting SafeHandle marshaling in native stubs. CI platform matrix: Azure DevOps private and public pipelines diverge—PRs may pass one and fail the other if platform-specific code added. Skia version pinning: Binding headers depend on specific Skia release; upstream breaking changes in Skia API require manual rebase of InterOP definitions. WASM/Blazor heap constraints: No explicit guidance in README on memory limits for WASM canvas operations—see .agents/skills/issue-repro/references/platform-wasm-blazor.md for gotchas.
🏗️Architecture
💡Concepts to learn
- P/Invoke (Platform Invoke) — SkiaSharp's entire architecture depends on safe P/Invoke marshaling between C# managed types and native Skia C++ library calls; understanding SafeHandle wrappers and calling convention quirks is essential for binding maintenance.
- Retained vs. Immediate Mode Graphics — Skia (and thus SkiaSharp) uses immediate-mode rendering where drawing commands execute directly; this architectural choice affects frame caching strategies, especially for WASM where redraw cycles differ from native platforms.
- SafeHandle for Resource Management — SkiaSharp wraps native Skia objects (SKSurface, SKCanvas, SKPaint) in SafeHandle subclasses to guarantee cleanup via finalizers; incorrect handle lifecycle can cause native memory leaks across platforms.
- GPU Acceleration via GrContext — Skia's GrContext enables hardware-accelerated rendering on platforms with GPU support (Metal on iOS/macOS, Vulkan on Linux, Direct3D on Windows); SkiaSharp bindings expose this but platform-specific initialization varies significantly.
- Multi-Targeting (.NET TFM) — SkiaSharp supports 10+ target frameworks (.NET 6, .NET Framework 4.8, .NET Standard 2.0, net6.0-ios, net6.0-android, etc.); managing platform-specific code paths and dependency resolution requires careful csproj structure.
- WebAssembly (WASM) Memory Model — WASM canvas drawing in Blazor environments has strict linear memory constraints and no native threading; SkiaSharp's WASM binding avoids multi-threaded Skia APIs and uses Emscripten's JavaScript interop layer.
- Native Asset Distribution Strategy — SkiaSharp.NativeAssets.Linux separates binaries per distro (musl vs. glibc, architecture variants) to avoid ABI mismatches; this pattern is specific to cross-distro .NET deployment and critical for Linux support.
🔗Related repos
google/skia— The upstream native C++ graphics library that SkiaSharp binds to; changes here cascade downstreamharfbuzz/harfbuzz— Text shaping engine that SkiaSharp integrates via HarfBuzzSharp for advanced typography supportdotnet/maui— Cross-platform UI framework that uses SkiaSharp.Views.Maui.Controls as rendering backend for custom graphicsunoplatform/uno— Platform abstraction layer (iOS/macOS/Android/WASM) that SkiaSharp targets via SkiaSharp.Views.Uno.WinUI packagemicrosoft/win-ui-3-samples— WinUI 3 (Windows App SDK) sample applications; demonstrates SkiaSharp.Views.Uno.WinUI integration patterns
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Create validation script for issue-triage skill outputs
The issue-triage skill has a validate-triage.py script but lacks integration testing. Create a comprehensive test suite that validates the triage schema outputs against real GitHub issues. This directly supports the agentic-workflows system and ensures quality of automated issue processing before deployment.
- [ ] Review .agents/skills/issue-triage/references/triage-schema.json and understand required fields
- [ ] Examine .agents/skills/issue-triage/scripts/validate-triage.py to identify gaps in validation logic
- [ ] Create pytest-based test suite in .agents/skills/issue-triage/tests/ with fixtures for common issue patterns
- [ ] Add tests for edge cases referenced in .agents/skills/issue-triage/references/anti-patterns.md
- [ ] Update .agents/skills/issue-triage/scripts/requirements.txt to include pytest dependencies
- [ ] Document test execution in a new TEST.md file within the skill directory
Implement fix-schema validation and auto-correction in issue-fix skill
The issue-fix skill has validate-fix.ps1 and validate-fix.py scripts, but the fix-schema.json validation appears incomplete. Create a schema validator that can catch common PR template violations early and provide actionable feedback to contributors, reducing review cycles.
- [ ] Review .agents/skills/issue-fix/references/fix-schema.json structure and constraints
- [ ] Study .agents/skills/issue-fix/references/pr-templates.md to identify validation rules
- [ ] Enhance validate-fix.py to parse and validate fix JSON against schema with detailed error messages
- [ ] Add JSON schema validation using jsonschema library
- [ ] Create integration tests in .agents/skills/issue-fix/tests/ using examples from .agents/skills/issue-fix/references/fix-examples.md
- [ ] Update .agents/skills/issue-fix/scripts/requirements.txt with jsonschema dependency
Add comprehensive skill documentation index and cross-linking system
The .agents/skills directory contains 9 distinct skills with fragmented documentation across SKILL.md and reference files. Create a unified skill registry with metadata (dependencies, prerequisites, inputs/outputs) and auto-generate a navigation system to help both agents and human contributors understand skill relationships and execution order.
- [ ] Create .agents/skills/REGISTRY.md with structured metadata for each skill (api-add-review, api-docs, issue-bulk-process, issue-fix, issue-repro, issue-triage, native-dependency-update, pr-commit-message)
- [ ] Add JSON-based skill manifest at .agents/skills/skills-manifest.json defining skill dependencies, inputs, outputs, and prerequisites
- [ ] Create .agents/SKILLS_INDEX.md with decision tree for contributors on which skill to use for different tasks
- [ ] Generate cross-reference links in each SKILL.md file pointing to related skills and workflow guides
- [ ] Update .agents/agents/agentic-workflows.agent.md to reference the new registry and call sequences
🌿Good first issues
- Add validation tests for fix-schema.json: The .agents/skills/issue-fix/references/fix-schema.json defines fix structure but there's no visible test suite validating real-world PRs against it. Create C# unit tests invoking validate-fix.py/.ps1 against sample fix JSON files.
- Document platform-specific SKSurface creation patterns: .agents/skills/issue-repro/ has platform guides but no consolidated example showing how SKSurface lifetime differs on WASM vs. Android. Add runnable code examples to .agents/skills/api-docs/references/patterns.md.
- Create Docker quickstart for local development: .agents/skills/issue-repro/references/platform-docker-linux.md exists but Dockerfile itself is minimal. Extend Dockerfile to bundle common dev dependencies (dotnet SDK, test runner, skia-dev headers) and document in README.
⭐Top contributors
Click to expand
Top contributors
- @mattleibow — 77 commits
- @ramezgerges — 14 commits
- @github-actions[bot] — 3 commits
- @4Darmygeometry — 3 commits
- @ebariche — 1 commits
📝Recent commits
Click to expand
Recent commits
5dd7682— [samples] Reduce SkiaFiddle WASM application size by ~60% (#3849) (ebariche)fd0baea— Run stale staging sweep daily instead of weekly (#3911) (mattleibow)884f306— Add content-based build caching with ADO Cache@2 (#3826) (mattleibow)d7256f3— Add automated Skia upstream sync workflow (#3825) (mattleibow)5d83581— Add workflow to persist agentic workflow data to aw-data branch (#3907) (mattleibow)c53542b— [docs] Release notes for 4.147.0 (#3882) (github-actions[bot])750dbe3— Fix SkiaSharp references for Uno Platform's Gallery sample (#3867) (ramezgerges)1be0e0f— Keep raw PR data in release notes files as HTML comment (#3877) (mattleibow)dbd0485— Add SKStream.GetData() for zero-copy stream-to-data conversion (#3772) (mattleibow)508fda5— Add animated WebP encoding support (SKWebpEncoder) (#3771) (mattleibow)
🔒Security observations
The SkiaSharp repository demonstrates a moderate security posture. The primary concerns are related to the agent automation framework, which uses Jinja2 templates and PowerShell scripts that could be vulnerable to injection attacks if inputs are not properly validated. Python dependency management lacks visible version pinning. No significant hardcoded secrets were detected in the file names. The codebase would benefit from implementing stricter input validation in agent workflows, PowerShell script code signing, pinned dependency versions, and a formal security policy. The graphics library component itself (SkiaSharp) appears to follow standard .NET/C++ practices, but the operational tooling around it requires security hardening.
- Medium · Jinja2 Template Injection Risk in Agent Scripts —
.agents/skills/issue-triage/scripts/ and related template files. The codebase uses Jinja2 (>=3.1) for template rendering in agent scripts, particularly in '.agents/skills/issue-triage/scripts/triage-report.md.jinja2'. If user input or untrusted data is passed to Jinja2 templates without proper sanitization, it could lead to Server-Side Template Injection (SSTI) attacks, potentially allowing arbitrary code execution. Fix: 1) Ensure all user inputs are validated and sanitized before passing to Jinja2 templates. 2) Use Jinja2's autoescape feature for HTML contexts. 3) Restrict the Jinja2 environment to only safe filters and globals. 4) Consider using Jinja2's SandboxedEnvironment for untrusted templates. 5) Implement strict input validation on agent workflow inputs. - Medium · PowerShell Script Security Concerns —
.agents/skills/issue-fix/scripts/ and .agents/skills/issue-repro/scripts/. Multiple PowerShell scripts (.ps1 files) are present in the codebase for persisting and validating fixes and reproductions. PowerShell scripts can be vulnerable to execution policy bypass, script injection, and privilege escalation if not properly secured. Fix: 1) Implement code signing for all PowerShell scripts. 2) Set ExecutionPolicy to RemoteSigned or AllSigned. 3) Avoid using Invoke-Expression or similar dynamic code execution. 4) Sanitize all inputs before passing to PowerShell cmdlets. 5) Run scripts with minimal required privileges. 6) Add security auditing for script execution. - Low · Python Script Dependencies Not Fully Specified —
.agents/skills/issue-triage/scripts/requirements.txt. The Python requirements.txt file in '.agents/skills/issue-triage/scripts/requirements.txt' is present but content is not visible. If dependencies are specified without pinned versions, it could lead to supply chain attacks or unexpected behavior from newer package versions. Fix: 1) Pin all Python package versions explicitly (e.g., package==1.2.3 instead of package>=1.2). 2) Use hash checking for critical dependencies. 3) Regularly audit dependencies for known vulnerabilities using tools like safety or pip-audit. 4) Consider using a lock file (poetry.lock, pipenv.lock) for reproducible builds. - Low · Potential Sensitive Information in Agent Documentation —
.agents/skills/ directory structure. The agent system contains multiple skill definitions and references that may handle issue data, reproduction cases, and CI/CD workflows. If these processes are not properly secured, sensitive information from issues or test environments could be exposed. Fix: 1) Implement strict access controls on agent skill definitions. 2) Ensure sensitive data (API keys, credentials, private issue information) is never logged or persisted. 3) Add data masking for sensitive information in test cases. 4) Implement audit logging for all agent actions. 5) Use environment variables for sensitive configuration, not hardcoded values. - Low · Missing SECURITY.md File —
Repository root. No SECURITY.md file is visible in the provided file structure. This file is important for disclosing security vulnerabilities responsibly and providing security contact information. Fix: Create a SECURITY.md file in the repository root that includes: 1) Security contact information. 2) Vulnerability disclosure policy. 3) Supported versions for security updates. 4) Instructions for reporting security issues privately.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.