picoe/Eto
Cross platform GUI framework for desktop and mobile applications in .NET
Single-maintainer risk — review before adopting
worst of 4 axesnon-standard license (Other); top contributor handles 93% of recent commits…
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 2w ago
- ✓4 active contributors
- ✓Other licensed
Show 5 more →Show less
- ✓CI configured
- ⚠Small team — 4 contributors active in recent commits
- ⚠Single-maintainer risk — top contributor 93% of recent commits
- ⚠Non-standard license (Other) — review terms
- ⚠No test directory detected
What would change the summary?
- →Use as dependency Concerns → Mixed if: clarify license terms
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 "Forkable" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/picoe/eto)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/picoe/eto on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: picoe/Eto
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/picoe/Eto 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
WAIT — Single-maintainer risk — review before adopting
- Last commit 2w ago
- 4 active contributors
- Other licensed
- CI configured
- ⚠ Small team — 4 contributors active in recent commits
- ⚠ Single-maintainer risk — top contributor 93% of recent commits
- ⚠ Non-standard license (Other) — review terms
- ⚠ 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 picoe/Eto
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/picoe/Eto.
What it runs against: a local clone of picoe/Eto — 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 picoe/Eto | Confirms the artifact applies here, not a fork |
| 2 | License is still Other | Catches relicense before you depend on it |
| 3 | Default branch develop exists | Catches branch renames |
| 4 | Last commit ≤ 45 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of picoe/Eto. If you don't
# have one yet, run these first:
#
# git clone https://github.com/picoe/Eto.git
# cd Eto
#
# 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 picoe/Eto and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "picoe/Eto(\\.git)?\\b" \\
&& ok "origin remote is picoe/Eto" \\
|| miss "origin remote is not picoe/Eto (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(Other)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"Other\"" package.json 2>/dev/null) \\
&& ok "license is Other" \\
|| miss "license drift — was Other at generation time"
# 3. Default branch
git rev-parse --verify develop >/dev/null 2>&1 \\
&& ok "default branch develop exists" \\
|| miss "default branch develop no longer exists"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 45 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~15d)"
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/picoe/Eto"
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
Eto.Forms is a cross-platform desktop GUI framework for .NET that abstracts platform-native toolkits (WPF on Windows, MonoMac on macOS, GTK# on Linux) behind a single C# API. It lets developers write one UI codebase that compiles to native applications with native look-and-feel on Windows, Mac, and Linux, plus experimental mobile support. Monorepo structure: core abstraction in Eto namespace (Eto.Forms, Eto.Drawing, Eto.IO, Eto.Misc per build/help/xml/), with platform-specific implementations likely in separate projects. Build system uses MSBuild (build/Build.proj, build/Common.Build.targets) with platform-specific targets (build/Common.Mac.targets). GtkSharp3 bindings vendored in lib/GtkSharp3/.
👥Who it's for
.NET developers building desktop applications who need to target multiple platforms (Windows/Mac/Linux) without rewriting UI code for each platform's native toolkit. Also relevant for ISVs migrating WinForms apps to modern cross-platform .NET.
🌱Maturity & risk
Production-ready but moderately active. The repo shows CI/CD pipelines (build.yml, publish.yml), organized release automation (.github/workflows/create-release.yml, manual-version-bump.yml), and is published on NuGet. Desktop support (WinForms, WPF, GTK#, MonoMac) is stable; mobile/iOS is explicitly noted as incomplete. Commit recency not visible in provided data, but the GitHub Actions setup and structured release process indicate active maintenance.
Moderate risk: the framework abstracts 4+ platform-specific toolkits (WinForms, WPF, MonoMac, GTK#), creating maintenance burden if upstream libraries change. Mobile support is incomplete. No test directory visible in top 60 files, raising questions about test coverage. The monolithic abstraction means API design changes affect all platform backends simultaneously, increasing breaking-change risk.
Active areas of work
Release automation is active (manual-version-bump.yml, create-release.yml workflows). The repo appears to use GitHub Discussions and Gitter for community engagement. Exact current work not visible from file list, but structured release pipeline and CI suggest ongoing maintenance cycles.
🚀Get running
Clone: git clone https://github.com/picoe/Eto.git. Build with ./build.sh (Unix) or build.cmd (Windows). See build/ directory for MSBuild orchestration via Build.proj.
Daily commands:
Desktop app: instantiate Application, create a Form, call app.Run(form) — see README examples. Framework handles platform detection and backend initialization. For dev work: build.sh or build.cmd compiles all backends and generates help documentation.
🗺️Map of the codebase
- README.md: Entry point describing framework capability, platform support (WinForms/WPF/MonoMac/GTK#), and hello-world examples in C# and F#.
- build/Build.proj: Master MSBuild orchestration file that defines how all platform backends are compiled and packaged.
- build/Common.Build.targets: Shared MSBuild configuration applied to all projects; defines build rules, output structure, and cross-platform compilation logic.
- build/Common.Mac.targets: macOS-specific build rules for MonoMac backend compilation and framework linking.
- .github/workflows/build.yml: CI pipeline that validates all platform backends compile and tests run on push/PR.
- .github/workflows/publish.yml: Release pipeline that publishes NuGet packages; shows how versioning and distribution are automated.
- lib/GtkSharp3/: Vendored GTK# bindings; critical for Linux backend functionality without external C library installation.
- .config/dotnet-tools.json: Local .NET tool configuration; may specify tools required for build (e.g., code generation, help building).
🛠️How to make changes
New UI control: add abstract definition in core Eto.Forms namespace, then implement in each platform backend (WinForms, WPF, MonoMac, GTK# handlers). Platform handlers likely live in platform-specific project folders (not visible in top 60 but structured per Common.targets). Update build/Common.Build.targets if adding new assemblies. Update build/help/xml/ for documentation.
🪤Traps & gotchas
No test directory visible in top 60 files — verify test location before writing tests. Platform backend selection is implicit (likely via Platform.Initialize() call in examples); understand that WinForms/WPF/MonoMac/GTK# are mutually exclusive at runtime, not compile-time. MonoMac backend may be deprecated or require older Mono versions — check .github/workflows/build.yml for which platforms are actively tested. GtkSharp3 is vendored but GTK native libraries must be installed on Linux at runtime. No package.json or .csproj visible in top 60, so actual project files likely in subdirectories not shown — explore src/ or similar.
💡Concepts to learn
- Platform Abstraction Layer (PAL) — Eto's entire architecture hinges on this pattern — understanding how abstract handler interfaces map to platform-specific implementations is critical to modifying or extending the framework.
- Handler Pattern (Bridge Pattern) — Each Eto control (e.g., Button, TextBox) delegates to a platform-specific handler; grasping this decouples control logic from platform code and is the core extension point.
- P/Invoke and Native Interop — WinForms and WPF backends invoke native Windows APIs; GTK# backend uses P/Invoke to call C GTK libraries. Essential when debugging platform-specific crashes or performance issues.
- MSBuild Project System — All compilation and package building uses MSBuild (Build.proj, Common.Build.targets); understanding conditional compilation for platform-specific builds is mandatory for working on this monorepo.
- Toolkit Abstraction (WinForms vs WPF vs GTK# vs Cocoa) — Eto hides four completely different UI toolkits behind one API; the tension between their different event models, layout systems, and capabilities is the root of most design decisions and debugging challenges.
- Immediate-Mode vs Retained-Mode Graphics — Eto.Drawing must abstract both immediate-mode (GDI+, Cairo) and retained-mode (WPF, Cocoa) graphics models; understanding this split explains rendering complexity and performance tradeoffs.
🔗Related repos
AvaloniaUI/Avalonia— Alternative cross-platform .NET UI framework using XAML; directly competes for same developer audience needing WPF-like APIs on Linux/Mac.dotnet/maui— Microsoft's official cross-platform UI framework for .NET; newer approach covering desktop and mobile, potentially superseding Eto for new projects.GtkSharp/GtkSharp— Upstream GTK# bindings library that Eto bundles (vendored in lib/GtkSharp3/); understanding this is essential for Linux backend hacking.mono/MonoMac— Upstream Cocoa bindings for macOS backend; Eto's MonoMac handler depends on this, now largely superseded by modern .NET for Mac.picoe/Eto.Veldrid— Companion GPU rendering library built on top of Eto; demonstrates how to extend Eto with high-performance graphics.
🪄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.
Add platform-specific integration tests for GTK# bindings (lib/GtkSharp3)
The repo contains GTK# bindings in lib/GtkSharp3 but lacks dedicated integration tests to verify these native interop bindings work correctly across Linux platforms. This is critical since GTK# is a key platform implementation. Adding tests would catch regressions in native marshaling and improve confidence in cross-platform rendering.
- [ ] Create new test project: test/Eto.Test.GtkSharp/GtkSharpInteropTests.cs
- [ ] Add tests for critical GTK# interop points: control initialization, event marshaling, and resource cleanup
- [ ] Add GitHub Actions workflow step in .github/workflows/build.yml to run tests on Ubuntu with GTK dependencies
- [ ] Reference existing test patterns from the samples folder to maintain consistency
Implement macOS-specific build verification in CI pipeline
The build system includes build/Common.Mac.targets but the current .github/workflows/build.yml and .github/workflows/publish.yml don't explicitly verify macOS builds on macOS runners. This creates blind spots for native macOS-specific code paths and Cocoa interop issues that only manifest on actual Apple Silicon/Intel hardware.
- [ ] Add macos-latest and macos-13 job matrices to .github/workflows/build.yml
- [ ] Create separate build targets in the CI workflow specifically for macOS: dotnet build with Mac-specific conditionals
- [ ] Add .github/workflows/build.yml step to run macOS-specific unit tests and validate .dylib linking
- [ ] Document macOS build prerequisites in README.md (Xcode version, native dependencies)
Add comprehensive Windows Forms to Eto migration guide with code examples
Eto.Forms is positioned as a cross-platform alternative to WinForms, but there's no structured migration guide for developers transitioning existing WinForms projects. Given the mature WinForms codebase in many organizations, a detailed mapping guide with side-by-side examples (in docs/ or as a wiki article with embedded links) would significantly lower adoption barriers.
- [ ] Create docs/winforms-migration-guide.md with control mapping (Form→Window, Button→Button, etc.)
- [ ] Add example code snippets comparing WinForms event handling with Eto.Forms equivalents (use samples folder as reference)
- [ ] Include API compatibility table highlighting behavioral differences (threading model, DPI handling, native platform differences)
- [ ] Link this guide from README.md and create a GitHub Discussion pinned post to support community questions
🌿Good first issues
- Add unit tests for Eto.Drawing primitives (Color, Size, Point) — top 60 file list shows no test/ directory, indicating test infrastructure gap. Start with a single drawing class and write xUnit/NUnit tests.
- Document GTK# / Linux backend setup in CONTRIBUTING guide — build/help/ exists but no explicit GTK# installation instructions visible. Add section to wiki or README covering gdk-sharp, cairo-sharp, atk-sharp version requirements.
- Create a sample application for mobile/iOS backend (noted as incomplete) — add example in examples/ demonstrating iOS Forms usage to unblock community feedback on what's needed for mobile parity.
⭐Top contributors
Click to expand
Top contributors
- @cwensley — 93 commits
- @clicky — 3 commits
- @Descolada — 3 commits
- @acormier — 1 commits
📝Recent commits
Click to expand
Recent commits
ffabebb— Merge pull request #2939 from cwensley/curtis/mac-custom-cell-text-color-dark-light (cwensley)49c434b— Merge pull request #2938 from cwensley/curtis/mac-use-monomac-with-local-eto (cwensley)c4593dc— Mac: Fix CellEventArgs.CellTextColor after switching from dark to light (cwensley)f2e6fe2— Mac: Include monomac when using LocalEtoPath for the Sdk (cwensley)83b7efd— Merge pull request #2937 from cwensley/curtis/ime-no-beeps-please-when-handled (cwensley)d78250e— Mac: Don't beep during IME composition when e.Handled = true (cwensley)f5f6b27— Merge pull request #2936 from cwensley/curtis/mac-activate-when-debugging (cwensley)e433d83— Mac: Activate app on startup when debugging by default (cwensley)212ed68— Merge pull request #2935 from cwensley/curtis/ime-apis (cwensley)4aa7d7d— Add Drawable TextComposition & TextInsertionBoundsRequested APIs (cwensley)
🔒Security observations
The Eto.Forms codebase demonstrates reasonable security practices as a cross-platform GUI framework, but has notable areas for improvement. Primary concerns include: (1) Bundled binary dependencies that bypass modern package management and vulnerability tracking, (2) Debug symbols exposed in distributed libraries, (3) Legacy COM interop that requires careful security review, and (4) GitHub workflow security hardening opportunities. No hardcoded secrets or obvious injection vulnerabilities were identified from the file structure. The project would benefit from migrating to NuGet-based dependency management and implementing automated security scanning in the CI/CD pipeline.
- Medium · Bundled Third-party Libraries Without Version Control —
lib/GtkSharp3/, lib/SHDocVw/, lib/webkit-sharp/. The repository contains pre-compiled binary dependencies in the lib/ directory (GtkSharp3, SHDocVw, webkit-sharp) that are checked into version control. These binaries lack explicit version pinning and vulnerability tracking, making it difficult to identify and patch known security issues in dependencies. Fix: Migrate to NuGet package management for all external dependencies, implement dependency scanning tools (e.g., OWASP Dependency-Check, Snyk), and establish a process for regular security updates of third-party libraries. - Low · Potential Information Disclosure via Debug Symbols —
lib/GtkSharp3/*.dll.mdb files. The bundled libraries include .mdb debug symbol files (.dll.mdb), which can expose internal implementation details and source code locations. These should not be distributed in production packages. Fix: Exclude .mdb and other debug symbol files from production builds and NuGet packages. Use symbol servers for developers who need debugging information. - Low · Missing Security Headers in GitHub Workflows —
.github/workflows/. The GitHub workflow configuration files (.github/workflows/) may benefit from additional security best practices such as signed commits enforcement, branch protection rules, and secrets scanning. Fix: Enable GitHub's branch protection rules, require signed commits, enable secret scanning and push protection, and review workflow permissions (use least privilege principle for GITHUB_TOKEN). - Low · Potential Insecure Interop Usage —
lib/SHDocVw/Interop.SHDocVw.dll. The presence of Interop.SHDocVw.dll (COM interop for Internet Explorer) indicates platform-specific interoperability code. Legacy COM interop can introduce security risks if not properly validated, particularly with untrusted input. Fix: Review all COM interop usage for input validation, avoid passing untrusted data to COM interfaces, consider modern alternatives, and apply principle of least privilege to COM object instantiation.
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.