PistonDevelopers/conrod
An easy-to-use, 2D GUI library written entirely in Rust.
Stale — last commit 4y ago
weakest axisnon-standard license (Other); last commit was 4y ago
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.
- ✓11 active contributors
- ✓Other licensed
- ✓CI configured
Show all 7 evidence items →Show less
- ✓Tests present
- ⚠Stale — last commit 4y ago
- ⚠Concentrated ownership — top contributor handles 62% of recent commits
- ⚠Non-standard license (Other) — review terms
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/pistondevelopers/conrod)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/pistondevelopers/conrod on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: PistonDevelopers/conrod
Generated by RepoPilot · 2026-05-09 · 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/PistonDevelopers/conrod 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 — Stale — last commit 4y ago
- 11 active contributors
- Other licensed
- CI configured
- Tests present
- ⚠ Stale — last commit 4y ago
- ⚠ Concentrated ownership — top contributor handles 62% of recent commits
- ⚠ Non-standard license (Other) — review terms
<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 PistonDevelopers/conrod
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/PistonDevelopers/conrod.
What it runs against: a local clone of PistonDevelopers/conrod — 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 PistonDevelopers/conrod | Confirms the artifact applies here, not a fork |
| 2 | License is still Other | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 1602 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of PistonDevelopers/conrod. If you don't
# have one yet, run these first:
#
# git clone https://github.com/PistonDevelopers/conrod.git
# cd conrod
#
# 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 PistonDevelopers/conrod and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "PistonDevelopers/conrod(\\.git)?\\b" \\
&& ok "origin remote is PistonDevelopers/conrod" \\
|| miss "origin remote is not PistonDevelopers/conrod (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 master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 4. Critical files exist
test -f "conrod_core/src" \\
&& ok "conrod_core/src" \\
|| miss "missing critical file: conrod_core/src"
test -f "Cargo.toml" \\
&& ok "Cargo.toml" \\
|| miss "missing critical file: Cargo.toml"
test -f "backends/conrod_winit/src/lib.rs" \\
&& ok "backends/conrod_winit/src/lib.rs" \\
|| miss "missing critical file: backends/conrod_winit/src/lib.rs"
test -f "backends/conrod_glium/src/lib.rs" \\
&& ok "backends/conrod_glium/src/lib.rs" \\
|| miss "missing critical file: backends/conrod_glium/src/lib.rs"
test -f "conrod_core/src/event.rs" \\
&& ok "conrod_core/src/event.rs" \\
|| miss "missing critical file: conrod_core/src/event.rs"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 1602 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~1572d)"
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/PistonDevelopers/conrod"
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
Conrod is a 2D immediate-mode GUI library written entirely in Rust that compiles to native applications across platforms. It provides a comprehensive widget system (buttons, text fields, sliders, canvas, etc.) with a builder-pattern API and supports multiple rendering backends (glium, gfx, wgpu, vulkano, piston). The core abstraction sits in conrod_core, while conrod_winit simplifies integration with the winit windowing library. Workspace monorepo with conrod_core as the foundational crate (core traits, widgets, themes, immediate-mode Ui logic), conrod_derive providing procedural macros (WidgetCommon, WidgetStyle), and 6 backend crates under backends/ (conrod_glium, conrod_gfx, conrod_winit, conrod_piston, conrod_rendy, conrod_vulkano, conrod_wgpu). Examples live in backends/conrod_glium/examples/ with shared code in backends/conrod_example_shared/src/lib.rs. Assets (fonts, images) sit in assets/.
👥Who it's for
Rust developers building cross-platform desktop applications who want a lightweight, immediate-mode GUI without the complexity of retained-mode systems or dependency on heavyweight frameworks. Game developers and systems programmers who need fast, predictable UI rendering integrated with their rendering pipelines.
🌱Maturity & risk
The project is mature but abandoned by its original maintainer as of mid-2021 (see issue #1454 in README). It has solid production-quality code, comprehensive examples in backends/conrod_glium/examples/, and CI via .github/workflows/conrod.yml, but no active development. The README explicitly recommends migrating to egui for new projects. Verdict: Mature but unmaintained—suitable for existing projects, not recommended for new ones.
Single-maintainer abandonment is the critical risk; the original author stepped down and no active replacement maintainer is confirmed. Dependency churn risk: the project depends on winit, glium, gfx, and other graphics libraries that have evolved significantly since 2021, creating potential compatibility issues with modern Rust toolchains. No evidence of recent commits or active issue triage in the README snapshot provided.
Active areas of work
The repository is in maintenance-only mode. The original maintainer has formally stepped down (README notice + issue #1454). No active feature work or new commits are visible in the provided file snapshot. The project remains available for use and existing bug reports, but no roadmap exists for new capabilities.
🚀Get running
git clone https://github.com/PistonDevelopers/conrod.git
cd conrod
cargo build --workspace
# Run a glium-backed example:
cargo run --example hello_world --manifest-path backends/conrod_glium/Cargo.toml
Daily commands:
# Build all crates
cargo build --workspace
# Run the comprehensive example (all widgets):
cargo run --example all_winit_glium --manifest-path backends/conrod_glium/Cargo.toml
# Run hello_world:
cargo run --example hello_world --manifest-path backends/conrod_glium/Cargo.toml
# Run threaded variant:
cargo run --example all_winit_glium_threaded --manifest-path backends/conrod_glium/Cargo.toml
🗺️Map of the codebase
conrod_core/src— Core library module containing all fundamental widget, event, and rendering abstractions—every developer must understand the widget trait system and event loop hereCargo.toml— Workspace root defining all member crates (core, backends, winit integrations); essential for understanding dependency resolution and feature flags across backendsbackends/conrod_winit/src/lib.rs— Primary window event integration layer that bridges OS input events to conrod's event system; most applications depend on thisbackends/conrod_glium/src/lib.rs— Reference backend implementation using Glium for rendering; demonstrates the standard pattern for graphics pipeline integrationconrod_core/src/event.rs— Event definition and routing system for mouse, keyboard, and window events; critical for understanding input handling flowconrod_core/src/graph— Widget graph and layout engine; core to how widgets are positioned, sized, and stored in the UI treeREADME.md— Contains critical notice that original maintainer is stepping down and recommends egui as replacement; essential context for all contributors
🧩Components & responsibilities
- conrod_core (Widget Library) — Defines Widget trait, event types, layout engine, color/cursor/border primit
🛠️How to make changes
Add a Custom Widget
- Define widget struct and builder in conrod_core/src/widget/ with state and builder fields (
conrod_core/src/widget/custom.rs) - Implement Widget trait from conrod_core providing update() and draw() methods (
conrod_core/src/widget/custom.rs) - Register widget in conrod_core/src/widget/mod.rs exports (
conrod_core/src/widget/mod.rs) - Create example demonstrating widget in backends/conrod_glium/examples/custom_widget.rs (
backends/conrod_glium/examples/custom_widget.rs)
Add a New Graphics Backend
- Create new backend crate directory backends/conrod_newapi/ with Cargo.toml (
backends/conrod_newapi/Cargo.toml) - Implement Renderer trait from conrod_core in src/lib.rs to handle primitive drawing (
backends/conrod_newapi/src/lib.rs) - Add vertex/shader definitions for the graphics API (see vulkano or wgpu patterns) (
backends/conrod_newapi/src/shaders/shader.vert) - Create example application using new backend in examples/all_winit_newapi.rs (
backends/conrod_newapi/examples/all_winit_newapi.rs) - Register new backend in workspace Cargo.toml members array (
Cargo.toml)
Integrate with Alternative Window Framework
- Create new backend crate backends/conrod_newwindow/ with window event types (
backends/conrod_newwindow/src/lib.rs) - Implement event conversion from new framework to conrod_core::event::Event (
backends/conrod_newwindow/src/event.rs) - Create window setup and event loop integration following conrod_winit pattern (
backends/conrod_newwindow/src/lib.rs) - Add to workspace members in Cargo.toml for CI/build inclusion (
Cargo.toml)
🔧Why these technologies
- Rust — Memory safety without GC, zero-cost abstractions for performance-critical rendering, strong type system enforces UI consistency
- Immediate Mode GUI — Stateless widget definitions reduce state management complexity, natural fit for retained widget graph with per-frame rebuilding
- Multiple Graphics Backends (Glium, Vulkan, wgpu, Rendy) — Decouples core logic from graphics API, allows target platform selection without core library changes
- Builder Pattern for Widgets — Ergonomic API for composing widget hierarchies, type-safe configuration without verbose struct initialization
- Workspace Monorepo — Core library (conrod_core) isolated from backends enables experimentation; shared examples reduce duplication
⚖️Trade-offs already made
-
Immediate mode execution model with retained widget graph
- Why: Immediate mode simplifies widget logic (no persistent state), but retained graph maintains layout/hierarchy across frames for efficiency
- Consequence: Slightly more complex than pure immediate mode (e.g. egui) but more efficient than pure retained mode; developers must understand state rebuilding semantics
-
Separate rendering backends instead of unified renderer
- Why: Leverage platform-specific graphics APIs for performance and modern API features (e.g., Vulkan bindless, wgpu WebGPU portability)
- Consequence: Higher maintenance burden (shader duplication across backends); users locked to backend choice at compile time
-
No native text layout engine—relies on glyph_brush or external rendering
- Why: Text rendering is notoriously complex (Unicode, shaping, kerning); delegating to external crates reduces scope
- Consequence: Simpler core but harder for users to implement custom text rendering; text widget behavior varies by backend
-
Immutable core abstractions with builder-only mutation
- Why: Prevents accidental state races and makes widget behavior deterministic across frames
- Consequence: Ergonomic for most use cases but verbose for complex stateful widgets; pushes mutable state to application layer
🚫Non-goals (don't propose these)
- Does not provide text layout or shaping—delegates to external crates (glyph_brush, rustybuzz)
- Does not include audio, input method editing (IME), or accessibility features (WCAG compliance)
- Does not support cross-process or network UI remoting
- Not a game engine—focused only on 2D GUI, not 3D rendering or physics
- Does not provide data binding or reactive/observable state management—UI updates driven by application loop
- No web/HTML/DOM support—purely native Rust API
🪤Traps & gotchas
Version resolver: resolver = "2" is required in root Cargo.toml (set due to wgpu's requirements)—do not downgrade to v1. Backend compatibility: Each backend (glium, gfx, wgpu, vulkano) may have stale dependencies; compatibility with latest Rust/OS graphics APIs is not guaranteed post-2021. Example paths: Examples use relative paths to assets in assets/ and support code; running from wrong directory will fail to load fonts/images. Immediate-mode assumption: UI state is not persisted between frames; learners expecting retained-mode (widget objects persist) will be confused. No official WASM support: winit+conrod works only on native platforms; web deployment is unsupported.
🏗️Architecture
💡Concepts to learn
- Immediate-mode GUI (IMGUI) — Conrod's core architectural choice; UI is rebuilt fresh each frame by calling widget methods, enabling data-driven design without widget object lifecycle management—critical to understanding how
Ui::set_widgets()works - Widget trait and builder pattern — Conrod's extensibility mechanism; every widget implements
Widgettrait and uses fluent builder methods to configure appearance/behavior without mutable state, essential for custom widget development - Ui graph (graph-based layout) — Conrod internally maintains a directed acyclic graph (DAG) of widgets to resolve parent-child relationships and constraint-based layout; understanding this explains how position/size are calculated
- Procedural macros (WidgetCommon, WidgetStyle) — Conrod_derive's
#[derive(...)]macros reduce boilerplate for custom widgets by auto-generating common trait methods; understanding macro expansion is needed to customize widget derivation - Theme system (styling + inheritance) — Conrod decouples visual styling into
Themeobjects supporting font defaults, colors, padding—critical for building multi-themed applications and understanding why widget appearance is configurable - Event loop integration (polling vs callbacks) — Conrod requires manual event feeding into the Ui each frame via
Ui::input()rather than callback-based event handling; understanding this prevents architectural mismatches when integrating with winit or custom windowing - Hardware-abstracted rendering (gfx/wgpu/vulkano backends) — Conrod decouples layout logic (conrod_core) from rendering, allowing multiple graphics APIs; understanding backend abstraction is necessary to port to new platforms or optimize rendering
🔗Related repos
emilk/egui— Direct modern replacement recommended in Conrod's README; Rust immediate-mode GUI with better maintenance and simpler integrationredox-os/orbtk— Alternative Rust-native GUI library with retained-mode architecture; targets similar use cases but different design philosophyrust-windowing/winit— Windowing + event-handling library that Conrod depends on; essential for cross-platform window/input integrationgfx-rs/gfx— Hardware abstraction layer for graphics used by conrod_gfx backend; foundational for rendering across APIsPistonDevelopers/piston— Game engine framework that integrates Conrod; legacy backend included for compatibility
🪄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 GitHub Actions CI workflow to test all backend crates
The repo has 8 backend crates (conrod_glium, conrod_gfx, conrod_piston, conrod_rendy, conrod_vulkano, conrod_wgpu, conrod_winit, conrod_example_shared) but .github/workflows/conrod.yml likely only tests a subset. Each backend has different dependencies and may fail independently. A comprehensive matrix-based workflow would catch backend-specific breakages early.
- [ ] Review current .github/workflows/conrod.yml to see which backends are tested
- [ ] Create a GitHub Actions matrix job that tests:
cargo test --all-featuresfor conrod_core and conrod_derive, plus individualcargo buildfor each backend in backends/ - [ ] Add separate test step for examples in backends/conrod_glium/examples/ and backends/conrod_piston/examples/ to ensure they compile
- [ ] Configure workflow to run on push to main and all PRs
Add unit tests for conrod_core event handling in src/event.rs
The conrod_core crate is the heart of the library but likely lacks comprehensive tests for event processing. With multiple backends (winit, piston, gfx, etc.) feeding events into conrod_core, unit tests would validate event transformation logic before backend-specific integration tests. See backends/conrod_piston/src/event.rs and backends/conrod_glium examples for event usage patterns.
- [ ] Examine conrod_core/src/event.rs structure and identify core event types (Input, Motion, etc.)
- [ ] Create conrod_core/tests/event_handling.rs with tests for: event conversion, widget state updates from events, event filtering by widget bounds
- [ ] Add tests for the Widget trait's event handler interface using mock widgets
- [ ] Test interaction chains (e.g., button press → hover state → release → action)
Reorganize conrod_rendy shader assets into dedicated shader module
Shader files in backends/conrod_rendy/src/shaders/ (shader.vert, shader.frag, vert.spv, frag.spv) are mixed with Rust code. The precompiled SPV files should be embedded in the binary or loaded from a proper assets directory. This would reduce maintenance burden and align with conrod's asset structure (see assets/ folder for fonts/images).
- [ ] Review backends/conrod_rendy/src/lib.rs to understand current shader loading mechanism
- [ ] Move .spv binary files to backends/conrod_rendy/assets/shaders/
- [ ] Update backends/conrod_rendy/src/lib.rs to use include_bytes!() macro or embed shaders at compile time instead of runtime file loading
- [ ] Update backends/conrod_rendy/Cargo.toml to document shader compilation process for maintainers
- [ ] Add comment in backends/conrod_rendy/src/shaders/README.md explaining shader recompilation steps
🌿Good first issues
- Add missing unit tests for
conrod_core/src/widget/text_edit.rscharacter insertion/deletion logic. Currently onlyconrod_glium/examples/text_edit.rsprovides integration coverage; no isolated tests exist for edge cases (multi-byte UTF-8, cursor boundaries, selection).: Medium - Document the Builder pattern and custom widget creation workflow by filling in the Guide sections 5 ('Designing Custom Widgets using the Widget trait') and 4 ('Using and Customising Themes') mentioned in README. These are marked as not-yet-implemented but critical for new contributors.: Low
- Add a
conrod_wgpubackend example (similar toall_winit_glium.rs) that uses the modern wgpu API instead of glium. The backend crate exists (backends/conrod_wgpu/) but has no example, making it difficult to verify functionality.: Medium
⭐Top contributors
Click to expand
Top contributors
- @mitchmindtree — 62 commits
- @t18b219k — 12 commits
- @yutannihilation — 9 commits
- @alvinhochun — 6 commits
- @shinmili — 3 commits
📝Recent commits
Click to expand
Recent commits
8b4e0d3— Merge pull request #1455 from mitchmindtree/stepping-away (mitchmindtree)566f267— Add notice of stepping down as maintainer (mitchmindtree)88424a4— Merge pull request #1445 from AsyncBanana/patch-1 (shanehandley)11b0d41— Add conrod_wgpu to README (AsyncBanana)7beb3b3— Merge pull request #1441 from mitchmindtree/publish-0.76 (mitchmindtree)49a97e3— Publish version 0.76 (mitchmindtree)2caf9a1— Remove unnecessary comments in conrod_vulkano backend (mitchmindtree)3745308— Merge pull request #1440 from mitchmindtree/wgpu-0.11 (mitchmindtree)a8ac861— Merge pull request #1439 from t18b219k/master (mitchmindtree)7347478— Updateconrod_wgpuforwgpuversion0.11(mitchmindtree)
🔒Security observations
The conrod GUI library presents a moderate security concern primarily due to its unmaintained status. While the static analysis reveals no obvious injection vulnerabilities, hardcoded secrets, or critical misconfigurations in the visible file structure, the fact that the original maintainer is no longer maintaining the project is a significant risk factor. The codebase maintains multiple graphics backends with substantial dependency chains, increasing the attack surface. No Dockerfile or infrastructure vulnerabilities are apparent from the provided structure. Projects using conrod should plan migration to actively maintained alternatives (egui) or establish independent security monitoring and patching procedures. The code itself appears well-structured for a Rust project with proper workspace organization, but without active maintenance, it will accumulate technical debt and potential security vulnerabilities over time.
- Medium · Unmaintained Project - Security Support Ended —
README.md, Project Status. The original maintainer has stepped down from maintaining conrod. The README explicitly states that the maintainer will no longer be maintaining the project. This means security vulnerabilities discovered in the future may not be patched, and dependencies may become outdated. The project recommends using 'egui' as a replacement. Fix: Consider migrating to actively maintained alternatives like egui. If continuing to use conrod, establish a process to monitor and patch security vulnerabilities independently, and regularly audit dependencies for known CVEs. - Low · Multiple Backend Dependencies - Increased Attack Surface —
Cargo.toml workspace members, backends/. The project maintains multiple graphics backends (gfx, glium, piston, rendy, vulkano, wgpu) each with their own dependency chains. This significantly increases the attack surface and the number of transitive dependencies that could introduce vulnerabilities. Managing security across multiple backend implementations increases maintenance burden. Fix: Regularly audit all backend dependencies for CVEs using 'cargo-audit'. Consider documenting which backends are actively maintained and recommended. Implement automated dependency checking in CI/CD pipeline. Only include backends that are actively maintained and used. - Low · Workspace Resolver v2 Without Explicit MSRV —
Cargo.toml. The workspace uses resolver = '2' which was introduced in Rust 1.51. While this is generally safe and recommended, the codebase does not appear to specify a Minimum Supported Rust Version (MSRV). This could lead to unexpected build failures or security issues on older toolchains. Fix: Add an explicit rust-version field to Cargo.toml specifying the MSRV. This ensures consistency across all dependencies and makes it clear which Rust versions are supported and have been tested for security.
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.