RepoPilotOpen in app β†’

marc2332/freya

Cross-platform and non-web GUI library for πŸ¦€ Rust powered by 🎨 Skia.

Healthy

Healthy across all four use cases

weakest axis
Use as dependencyHealthy

Permissive license, no critical CVEs, actively maintained β€” safe to depend on.

Fork & modifyHealthy

Has a license, tests, and CI β€” clean foundation to fork and modify.

Learn fromHealthy

Documented and popular β€” useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture β€” runnable as-is.

  • βœ“Last commit today
  • βœ“11 active contributors
  • βœ“MIT licensed
Show all 6 evidence items β†’
  • βœ“CI configured
  • βœ“Tests present
  • ⚠Single-maintainer risk β€” top contributor 82% of recent commits

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.

Variant:
RepoPilot: Healthy
[![RepoPilot: Healthy](https://repopilot.app/api/badge/marc2332/freya)](https://repopilot.app/r/marc2332/freya)

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/marc2332/freya on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: marc2332/freya

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:

  1. 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.
  2. 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.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/marc2332/freya 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
  • 11 active contributors
  • MIT licensed
  • CI configured
  • Tests present
  • ⚠ Single-maintainer risk β€” top contributor 82% of recent commits

<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 marc2332/freya repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale β€” regenerate it at repopilot.app/r/marc2332/freya.

What it runs against: a local clone of marc2332/freya β€” 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 marc2332/freya | 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 |

<details> <summary><b>Run all checks</b> β€” paste this script from inside your clone of <code>marc2332/freya</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of marc2332/freya. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/marc2332/freya.git
#   cd freya
#
# 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 marc2332/freya and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "marc2332/freya(\\.git)?\\b" \\
  && ok "origin remote is marc2332/freya" \\
  || miss "origin remote is not marc2332/freya (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 "crates/freya/Cargo.toml" \\
  && ok "crates/freya/Cargo.toml" \\
  || miss "missing critical file: crates/freya/Cargo.toml"
test -f "crates/freya-core/src" \\
  && ok "crates/freya-core/src" \\
  || miss "missing critical file: crates/freya-core/src"
test -f "crates/torin/src" \\
  && ok "crates/torin/src" \\
  || miss "missing critical file: crates/torin/src"
test -f "crates/freya-winit/src" \\
  && ok "crates/freya-winit/src" \\
  || miss "missing critical file: crates/freya-winit/src"
test -f "crates/freya-components/src" \\
  && ok "crates/freya-components/src" \\
  || miss "missing critical file: crates/freya-components/src"

# 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/marc2332/freya"
  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).

</details>

⚑TL;DR

Freya is a cross-platform, declarative native GUI library for Rust that renders using Skia, enabling developers to build desktop applications with a React-like component model and state management. It powers UI through a custom rendering engine (Ragnarok) with layout via Torin, replacing web-based approaches like Electron with native performance and true Rust/memory safety. Monorepo with 24 workspace crates: crates/freya is the main entry point, crates/freya-core provides the component/state system, crates/ragnarok handles rendering, crates/torin manages layout, and crates/freya-winit bridges the windowing system. Examples live in examples/ (including full apps like ai-chat), with documentation in book/ (mdBook format).

πŸ‘₯Who it's for

Rust developers building desktop applications who want modern declarative UI patterns (components, hooks, state) without JavaScript overhead or web runtime dependencies. Contributors range from GUI library enthusiasts to developers building tools that need cross-platform native performance.

🌱Maturity & risk

Actively developed but pre-stable: the main branch recently underwent a major rewrite (PR #1351), currently at version 0.4.0-rc.19. It has comprehensive CI/CD (14 GitHub Actions workflows), an organized monorepo of 24 crates, and rich examples, but the RC status and recent architecture changes indicate it's not yet production-ready for all use cases.

Moderate risk from single-maintainer dependency (marc2332) and rapid architectural changes (recent full rewrite); however, the project mitigates this with extensive test coverage, active GitHub workflows, and a Discord community of ~1000+ members. The RC version status means APIs may break; check CHANGELOG and release notes carefully before adoption.

Active areas of work

The project recently completed a major rewrite (PR #1351), updating the component model and rendering pipeline. Active CI runs on every PR (rust_build, rust_test, hotpath benchmarks). Codebase is 96.4% Rust, with ongoing work visible in release-drafter automation and active Android support (freya-android crate).

πŸš€Get running

git clone https://github.com/marc2332/freya.git
cd freya
cargo run --example component_button

For the full book/docs locally: cd book && mdbook serve.

Daily commands: For a basic example: cargo run --example component_button. For the entire workspace build: cargo build --workspace. Enable features like hotreload or devtools with cargo run --example <name> --features devtools. Development builds via just (Justfile detected in language stats).

πŸ—ΊοΈMap of the codebase

  • crates/freya/Cargo.toml β€” Root workspace member defining Freya's core features (hotpath, hotreload, devtools, performance) and dependencies that all contributors must understand
  • crates/freya-core/src β€” Core rendering and component lifecycle engineβ€”essential to understanding how Freya's declarative UI model works
  • crates/torin/src β€” Layout engine powering Freya's constraint-based layout system; must understand for UI positioning and sizing logic
  • crates/freya-winit/src β€” Cross-platform window and event handling via Winit; critical for platform abstraction and input processing
  • crates/freya-components/src β€” Pre-built component library (buttons, inputs, scrollviews, etc.); reference for component patterns and styling conventions
  • Cargo.toml β€” Workspace configuration defining all member crates and shared lint rules; must review before adding new modules
  • CLAUDE.md β€” AI-assistant-specific guidelines for this codebase; must read to understand conventions and context for code generation

πŸ› οΈHow to make changes

Add a New Built-in Component

  1. Create a new Rust module in crates/freya-components/src with component struct and impl block (crates/freya-components/src/my_component.rs)
  2. Implement the component function with #[component] macro, accepting props and returning Element (crates/freya-components/src/my_component.rs)
  3. Export the component in the module tree (pub mod) and add to lib.rs (crates/freya-components/src/lib.rs)
  4. Add styling hooks (use_theme or custom props) and test with freya-testing utilities (crates/freya-testing/src/lib.rs)

Add a New Animation Type

  1. Create a new animation struct in crates/freya-animation/src (e.g., anim_size.rs) mirroring anim_num.rs or anim_color.rs (crates/freya-animation/src/anim_size.rs)
  2. Implement Animatable and Animation traits with update, progress, and finish methods (crates/freya-animation/src/anim_size.rs)
  3. Add an easing module mapping function if needed (see easing.rs for standard curves) (crates/freya-animation/src/easing.rs)
  4. Register in hook.rs and export in lib.rs for use via use_animation hook (crates/freya-animation/src/hook.rs)
  5. Add tests in crates/freya-animation/tests/animation.rs (crates/freya-animation/tests/animation.rs)

Add Platform-Specific Feature (e.g., Android)

  1. Create new module under crates/freya-android/src (e.g., my_feature.rs) following keyboard.rs or status_bar.rs pattern (crates/freya-android/src/my_feature.rs)
  2. Implement JNI bindings or Android API calls using android-activity or NDK crate (crates/freya-android/src/my_feature.rs)
  3. Expose via public function in lib.rs and gate behind #[cfg(target_os = 'android')] (crates/freya-android/src/lib.rs)
  4. Update Cargo.toml with platform-specific dependencies (e.g., android-activity) (crates/freya-android/Cargo.toml)

Add a New Layout Constraint or Sizing Rule

  1. Understand the constraint model in crates/torin/src (likely a constraints.rs or sizing.rs module) (crates/torin/src)
  2. Add new constraint type or sizing enum variant to the layout trait/struct (crates/torin/src)
  3. Implement layout computation logic in the main algorithm (e.g., measure or compute methods) (crates/torin/src)
  4. Update crates/freya-core/src to parse and apply the new constraint from element styling (crates/freya-core/src)
  5. Add test cases and example usage in an example file or test module (crates/torin/src)

πŸ”§Why these technologies

  • Skia (via skia-safe crate) β€” High-performance, battle-tested graphics library used by Chromium; provides hardware acceleration and consistent rendering across Windows, macOS, Linux, iOS, Android
  • Winit (cross-platform window management) β€” Abstraction over OS window APIs (Win32, Cocoa, X11, Wayland) allowing single codebase to target desktop and mobile platforms
  • Component-based declarative UI (React-like model) β€” Simplifies state management and automatic re-renders; familiar to web developers; composability enables reusable component libraries
  • Constraint-based layout (Torin custom engine vs. CSS) β€” Faster layout computation than CSS; deterministic sizing; tailored for immediate-mode rendering; avoids browser bloat
  • Rust macros (#[component], routing derives) β€” Compile-time code generation reduces runtime overhead; type safety for props; ergonomic API sugar

βš–οΈTrade-offs already made

  • Custom layout engine (Torin) vs. CSS

    • Why: Simpler, faster, and more predictable than CSS parsing; avoids spec complexity; better fit for native UI performance targets
    • Consequence: Developers familiar only with CSS may have a learning curve; less alignment with web standards
  • Immediate-mode rendering + virtual DOM diffing vs. retained graphics scene

    • Why: Easier to reason about state; automatic re-renders on state changes; simpler to implement animations and dynamic UI
    • Consequence: Higher per-frame overhead than deeply optimized game engines; requires careful memoization to avoid redundant re-renders
  • JNI/NDK Android bindings in Rust vs. Kotlin wrapper

    • Why: Reduces FFI boundary crossings; keeps codebase unified in Rust; better memory safety
    • Consequence: Android platform-specific code can be verbose; requires knowledge of Android APIs and JNI boilerplate

πŸͺ€Traps & gotchas

No standard package.jsonβ€”this is pure Rust Cargo workspace; Node.js tools won't work. Skia dependency: project uses skia-safe which may require platform-specific build tools (C++ toolchain on some OSes). Recent major rewrite: main branch differs significantly from latest stable docs; always check GitHub branch/release notes. Android builds require Android NDK and Gradle setup (see crates/freya-android). Hotreload feature is opt-in and requires special build setup. CSS-like syntax is custom, not standard CSSβ€”check docs/examples for exact property names.

πŸ—οΈArchitecture

πŸ’‘Concepts to learn

  • Declarative UI & Virtual DOM diffing β€” Freya's entire component model is built on this React-inspired pattern; understanding how components re-render only when state changes is key to writing performant UI code
  • Flexbox layout β€” Torin implements a Flexbox-like layout engine; knowing flex properties (grow, shrink, basis, justify-content, align-items) is essential for positioning UI elements
  • Reactive state management & hooks β€” Freya uses Rust closures + interior mutability (use_state, use_memo) instead of traditional MVC; this pattern differs from OOP GUI paradigms and requires mental model shift
  • Trait-based polymorphism (Component trait) β€” Components in Freya are any type implementing the Component trait; understanding Rust trait bounds and dynamic dispatch is critical for extending the framework
  • Skia canvas rendering & paint operations β€” Ragnarok converts the component tree to Skia draw calls; basic understanding of canvas-based rendering (paths, fills, strokes, text) helps debug visual output
  • Interior mutability (RefCell, Rc) β€” Freya's state system relies on Rust's RefCell and Rc for mutable shared state without ownership transfer; essential for working with use_state and custom state hooks
  • CSS property parsing & cascading β€” Freya implements a custom CSS-like property system; understanding selector matching, specificity, and inheritance (inherited vs. non-inherited properties) applies here
  • rust-windowing/winit β€” Freya's windowing and event handling layer depends on Winit; understanding Winit events is crucial for custom input handling
  • rust-skia/rust-skia β€” Freya renders via skia-safe bindings to Skia C++; low-level graphics understanding requires reading Skia API docs and examples
  • DioxusLabs/dioxus β€” Alternative Rust UI framework with similar component/hook model but web-first; useful for comparing state management patterns and component design philosophy
  • helix-editor/helix β€” High-performance Rust TUI editor; demonstrates Rust GUI patterns at production scale and shows how to handle real-time rendering and event loops efficiently
  • tauri-apps/tauri β€” Popular Rust + web hybrid framework for desktop apps; Freya's positioning as 'native alternative to Electron/Tauri' makes it a direct comparison point

πŸͺ„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 integration tests for freya-router and freya-router-macro

The workspace includes freya-router and freya-router-macro crates, but there are no visible test files in the file structure. Router functionality is critical for navigation in GUI apps. Adding comprehensive integration tests would ensure the macro expansion works correctly and routing behaves as expected across platform targets.

  • [ ] Create tests/integration_tests.rs in crates/freya-router/tests/
  • [ ] Add tests for basic route definition, parameter extraction, and route matching
  • [ ] Add tests for freya-router-macro in crates/freya-router-macro/tests/ covering macro expansion edge cases
  • [ ] Test cross-platform behavior (especially for Android given crates/freya-android exists)
  • [ ] Run existing test suite to ensure no regressions

Add unit tests for freya-clipboard platform-specific implementations

crates/freya-clipboard/src/clipboard.rs likely contains platform-specific code (Windows/macOS/Linux/Android handling) but has no visible test file. Clipboard operations are critical for user interactions. Tests should verify read/write operations work correctly per platform and handle edge cases like empty clipboard or permission errors.

  • [ ] Create crates/freya-clipboard/tests/clipboard_integration.rs
  • [ ] Add platform-specific test modules (test_windows, test_macos, test_linux, test_android)
  • [ ] Test clipboard read/write operations with various data types (text, rich text, binary)
  • [ ] Add tests for error handling (permission denied, clipboard unavailable)
  • [ ] Test with freya-android/src/status_bar.rs integration if clipboard interacts with status bar

Create missing GitHub Actions workflow for freya-webview platform support

The workspace includes crates/freya-webview (a webview integration crate), but there's no dedicated build/test workflow in .github/workflows/ for it. Given the complexity of webview across platforms (macOS WebKit, Windows Edge WebView2, Linux webkit2gtk), a platform-specific workflow would catch regressions early.

  • [ ] Create .github/workflows/webview_test.yml with separate jobs for Linux, macOS, and Windows
  • [ ] Configure Linux job to install webkit2gtk-4.0 development headers
  • [ ] Configure macOS job to verify WebKit framework availability
  • [ ] Configure Windows job for Edge WebView2 runtime checks
  • [ ] Add the workflow trigger to pull_request and main branch pushes

🌿Good first issues

  • Add missing component documentation: many built-in components in crates/freya-components/src/ lack inline doc comments and examples; pick one (e.g., virtual_scrollview.rs, slider.rs) and add /// doc blocks with usage examples matching the style in button.rs.
  • Write integration tests for state persistence: crates/freya-core/src/ has hooks but tests/ may be sparse; create a test file demonstrating use_state + use_effect combinations, similar to React testing patterns, to cover state lifecycle edge cases.
  • Improve book documentation for custom component creation: book/src/ has guides but no concrete walkthrough of building a stateful custom component from scratch using the new rewrite API; add a chapter with copy-paste code and diagrams.

⭐Top contributors

Click to expand

πŸ“Recent commits

Click to expand
  • 15e343c β€” docs: add/update Nix setup instructions (#1821) (sectore)
  • 17e4788 β€” nix: add cargo-nextest (#1822) (sectore)
  • b7ee374 β€” chore(deps): Bump hotpath to v0.15 (#1817) (marc2332)
  • 97ce14c β€” chore(docs): Simplify and clean up async and freya-query docs (marc2332)
  • 36e04c6 β€” feat: Skia shader as a background fill variant (#1743) (LynithDev)
  • d0ea0f8 β€” chore: Use toolchain files as single source of truth (#1791) (sectore)
  • ee59a33 β€” docs(hotreload): Add hotreload docs (#1815) (marc2332)
  • 41f595b β€” fix(core): Fix relative overlay layer cap (#1814) (marc2332)
  • 0490d90 β€” chore(components): Simplify code of Calendar (#1813) (marc2332)
  • 8dfddea β€” fix(ci): Fix build example ci (#1818) (marc2332)

πŸ”’Security observations

Freya presents a generally reasonable security posture for a GUI library, with no critical vulnerabilities evident from the static analysis of the file structure and Cargo configuration. Primary concerns are: (1) use of pre-release versions (0.4.0-rc.19) which may not be production-ready, (2) incomplete dependency declarations in the Cargo.toml file, (3) components requiring deeper security audits (WebView, Clipboard, SQLite examples), and (4) potential exposure of DevTools in production. The codebase demonstrates good organization with dedicated security-related crates. Recommend: completing version stability before production release, conducting thorough security audits of WebView and clipboard handling, and ensuring development-only features cannot be exposed in release builds.

  • Medium Β· Incomplete Workspace Dependency Declaration β€” Cargo.toml - [workspace.dependencies] section. The Cargo.toml workspace dependencies section appears truncated at 'freya-router'. The dependency entry for 'freya-router-macro' and potentially other workspace members are cut off, which could lead to version mismatches or unintended dependency resolution if dependencies are specified elsewhere with different versions. Fix: Ensure all workspace members have complete and consistent dependency declarations. Verify that all crate versions are pinned to the same version (0.4.0-rc.19) to prevent supply chain inconsistencies.
  • Medium Β· Pre-release Version in Production Dependencies β€” Cargo.toml - All [workspace.dependencies] entries. The workspace uses pre-release versions (0.4.0-rc.19) across all internal dependencies. Pre-release versions may contain bugs, unfinished features, or security patches that haven't been fully vetted. This is concerning if used in production applications. Fix: Transition to stable releases (1.0.0 or higher) before production deployment. If pre-release is necessary, implement additional security testing and code review processes.
  • Low Β· SQLite Usage in Examples Without Explicit Security Context β€” examples/state_query_sqlite/. The workspace includes 'examples/state_query_sqlite' which suggests SQLite database usage. Without reviewing the actual implementation, it's unclear if proper parameterized queries are used consistently, which could lead to SQL injection vulnerabilities. Fix: Audit the SQLite example code to ensure all database queries use parameterized statements/prepared statements exclusively. Never concatenate user input directly into SQL queries.
  • Low Β· WebView Component Requires Security Review β€” crates/freya-webview/. The presence of 'crates/freya-webview' indicates embedded web content handling. WebView components can be attack vectors if not properly sandboxed or if they load untrusted content. Fix: Ensure WebView component: (1) validates all loaded URLs, (2) disables JavaScript execution for untrusted content, (3) implements proper content security policies, (4) uses the latest WebView backend with security patches.
  • Low Β· Clipboard Component Lacks Visibility on Content Validation β€” crates/freya-clipboard/. The 'crates/freya-clipboard' crate handles clipboard operations. Without inspecting the implementation, it's unclear if there are protections against malicious clipboard content that could be exploited if processed unsafely. Fix: Review clipboard content handling to ensure: (1) size limits are enforced, (2) content type validation occurs, (3) no arbitrary code execution from clipboard data, (4) proper error handling for malformed data.
  • Low Β· DevTools Feature May Expose Sensitive Information β€” Cargo.toml - [features] devtools entry. The 'devtools' feature is included in the crate features, which typically provides debugging capabilities. DevTools could potentially expose sensitive application state or internal data if not properly restricted in production builds. Fix: Ensure devtools feature is only enabled for debug builds. Add compile-time assertions or runtime checks to prevent devtools from functioning in release/production builds.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals β€” see the live page for receipts. Re-run on a new commit to refresh.

Healthy signals Β· marc2332/freya β€” RepoPilot