flxzt/rnote
Sketch and take handwritten notes.
Mixed signals — read the receipts
weakest axiscopyleft license (GPL-3.0) — review compatibility
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
- ✓20 active contributors
- ✓GPL-3.0 licensed
Show all 7 evidence items →Show less
- ✓CI configured
- ✓Tests present
- ⚠Concentrated ownership — top contributor handles 51% of recent commits
- ⚠GPL-3.0 is copyleft — check downstream compatibility
What would change the summary?
- →Use as dependency Concerns → Mixed if: relicense under MIT/Apache-2.0 (rare for established libs)
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/flxzt/rnote)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/flxzt/rnote on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: flxzt/rnote
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/flxzt/rnote 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 — Mixed signals — read the receipts
- Last commit today
- 20 active contributors
- GPL-3.0 licensed
- CI configured
- Tests present
- ⚠ Concentrated ownership — top contributor handles 51% of recent commits
- ⚠ GPL-3.0 is copyleft — check downstream compatibility
<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 flxzt/rnote
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/flxzt/rnote.
What it runs against: a local clone of flxzt/rnote — 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 flxzt/rnote | Confirms the artifact applies here, not a fork |
| 2 | License is still GPL-3.0 | Catches relicense before you depend on it |
| 3 | Default branch main exists | Catches branch renames |
| 4 | 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 flxzt/rnote. If you don't
# have one yet, run these first:
#
# git clone https://github.com/flxzt/rnote.git
# cd rnote
#
# 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 flxzt/rnote and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "flxzt/rnote(\\.git)?\\b" \\
&& ok "origin remote is flxzt/rnote" \\
|| miss "origin remote is not flxzt/rnote (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(GPL-3\\.0)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"GPL-3\\.0\"" package.json 2>/dev/null) \\
&& ok "license is GPL-3.0" \\
|| miss "license drift — was GPL-3.0 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"
# 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/flxzt/rnote"
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
Rnote is a vector-based drawing and handwritten note-taking application written in Rust and GTK4, targeting students and stylus users. It provides pressure-sensitive stroke rendering, PDF/image import-export, infinite canvas layouts, and native document formats (.rnote files), solving the gap between general-purpose graphics tools and specialized note-taking apps that understand academic and drawing tablet workflows. Monorepo with 4 crates: crates/rnote-compose (shape builders and geometry), crates/rnote-engine (core drawing logic), crates/rnote-cli (command-line tooling), crates/rnote-ui (GTK4 interface). Built via Meson (meson.build files throughout), Cargo for Rust dependencies (workspace.dependencies in Cargo.toml), and Python build helpers (build-aux/cargo_build.py, inno_build.py).
👥Who it's for
Students, teachers, and drawing tablet owners who need to sketch, annotate PDFs, and take handwritten notes with stylus pressure sensitivity. Contributors are Rust developers interested in GTK4 UI development, vector graphics, and cross-platform desktop applications.
🌱Maturity & risk
Actively developed and production-ready: version 0.14.2 with comprehensive CI/CD pipelines (.github/workflows/ci.yml, dist.yml, release-windows.yml), Flatpak distribution on Flathub, and cross-platform support (Linux, macOS via external bundle, Windows via Inno installer). However, the file format is explicitly noted as unstable and may break between versions.
Standard open source risks apply.
Active areas of work
Recent workflow maintenance (update-translations.yml, test-report.yml suggest active localization and testing). Nightly builds configured (nightly.yml), Windows release automation in place. No specific PR/milestone data visible in file list, but CI infrastructure is actively maintained.
🚀Get running
git clone https://github.com/flxzt/rnote.git
cd rnote
meson setup builddir
meson compile -C builddir
meson install -C builddir
Or via Cargo: cargo build --release -p rnote-ui. Requires Rust 1.89+, GTK 4.18+, and development headers (see BUILDING.md).
Daily commands:
Development mode: meson compile -C builddir && meson install -C builddir then run rnote. Or direct Cargo: cargo run -p rnote-ui --release. CLI only: cargo run -p rnote-cli --release -- --help. See BUILDING.md for platform-specific dependencies.
🗺️Map of the codebase
- crates/rnote-engine: Core rendering engine—handles stroke physics, canvas logic, and document model; all drawing features depend on this
- crates/rnote-ui: GTK4 interface implementation; main user-facing code and widget hierarchy
- crates/rnote-compose/src/builders/: Shape construction (arrows, coordinate systems, polygons); patterns for extending tool capabilities
- Cargo.toml: Workspace definition and shared dependency versions; centralized version control (0.14.2) and Rust MSRV (1.89)
- meson.build: Primary build configuration; defines compilation flags, feature gates, and platform-specific logic
- BUILDING.md: Developer setup guide; critical for first-time contributors on any platform
- .github/workflows/ci.yml: CI pipeline definition; shows testing, linting, and validation expectations
🛠️How to make changes
New drawing features: start in crates/rnote-compose/src/builders/ (e.g., arrowbuilder.rs) for shape logic and crates/rnote-engine/ for rendering pipeline. UI changes: crates/rnote-ui/ contains GTK4 widgets. CLI tools: crates/rnote-cli/src/ (create.rs, export.rs, import.rs, thumbnail.rs). Translations: update .github/workflows/update-translations.yml. Build system: Meson files (meson.build) define compilation, Python helpers in build-aux/ handle platform specifics.
🪤Traps & gotchas
File format instability: .rnote format may break between versions (stated in README)—migration logic or version negotiation may be needed. Meson + Cargo hybrid: build system uses both Meson and Cargo; pure Cargo cargo build may miss platform integrations (desktop file, icons, glib-compile-resources). GTK4 version pinning: requires GTK 4.18+ (gtk4 0.10.0 with v4_18 feature)—older systems will fail silently. Stylus input: pressure sensitivity and tablet detection is platform-dependent (via GTK4); behavior differs on Linux/Windows/macOS. Python 3 requirement: build-aux/*.py scripts need Python for Windows installer generation (inno_build.py). No Docker/devcontainer: no evidence of containerized dev environment; setup is manual per BUILDING.md.
💡Concepts to learn
- Pressure-Sensitive Stylus Rendering — Rnote's core differentiator—converting raw stylus pressure events into adaptive stroke widths requires understanding tablet input events (GTK4 event handling) and real-time rasterization; affects performance and visual fidelity.
- Vector-to-Raster Export Pipeline — Rnote exports to SVG, PDF, and PNG/JPEG; requires managing scale-invariant vector representations (Kurbo curves) and converting them to Cairo render contexts with proper DPI and compression—critical for document fidelity.
- Infinite Canvas with Viewport Clipping — Rnote supports infinite canvases and multiple layout modes; requires efficient spatial indexing and viewport-based rendering to avoid rendering off-screen content—impacts performance on large documents.
- Serialization with Flate2 Compression — .rnote file format uses Flate2 (zlib) compression; understanding the serialization layer (Serde + Flate2 wrapping) is essential for file format changes, migration, and backward compatibility.
- Builder Pattern for Composable Shapes — crates/rnote-compose implements builders (ArrowBuilder, CoordSystem builders) for incremental shape construction; understanding this pattern is key to extending tool capabilities and maintaining immutability.
- Cross-Platform Stylus Input via GTK4 — Stylus events behave differently on Linux, Windows, and macOS; GTK4 abstracts these, but understanding platform-specific event sequences (pressure, tilt, barrel buttons) is crucial for tool responsiveness.
- Meson + Cargo Hybrid Build System — Rnote uses Meson for top-level build orchestration (platform integration, resource compilation) and Cargo for Rust compilation; understanding this split prevents build failures and enables proper packaging for distributions.
🔗Related repos
xournalpp/xournalpp— Direct competitor: also a note-taking and PDF annotation app with stylus support, but C++ based; useful for feature comparison and UX design inspirationinkscape/inkscape— Vector graphics editor written in C++; shares rendering pipeline concepts (Cairo, curves) and shape tools that Rnote adaptsGNOME/gtk— GTK4 upstream repository; essential for understanding widget APIs, input handling, and desktop integration that Rnote depends ondimforge/parry— Collision detection and geometry library (parry2d-f64) that Rnote uses; useful for understanding shape intersection and selection logiclinebender/kurbo— Vector graphics math library (kurbo 0.11.2) providing curve types and transformations; core to Rnote's stroke and shape rendering
🪄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 comprehensive unit tests for rnote-compose builders module
The rnote-compose crate contains 13 different builder implementations (ArrowBuilder, EllipseBuilder, LineBuilder, etc.) in crates/rnote-compose/src/builders/ but there's no visible test directory or test coverage for these critical shape-building components. Given that builders are core to the drawing functionality, adding unit tests would catch regressions and improve code quality. This is a high-value addition since builders are used throughout the UI layer.
- [ ] Create tests directory in crates/rnote-compose/src/builders/
- [ ] Add unit tests for buildable.rs trait implementations covering all builder types
- [ ] Test edge cases like zero-length lines, invalid polygon vertices, and coordinate transformations
- [ ] Add integration tests verifying builder output produces valid geometries compatible with cairo-rs rendering
- [ ] Reference existing test patterns from crates/rnote-engine if available
Add validation and error handling tests for rnote-cli validators module
The CLI crate has a validators.rs module (crates/rnote-cli/src/validators.rs) that likely validates user inputs for import/export operations and file paths, but there are no visible tests for validation edge cases. Given that the CLI is a critical user-facing interface (with import, export, create, and thumbnail commands), comprehensive validator tests would prevent silent failures and improve UX for batch operations.
- [ ] Create or expand tests in crates/rnote-cli/src/validators.rs
- [ ] Add tests for file path validation (invalid characters, non-existent paths, permissions)
- [ ] Test format validation for import/export (unsupported file types, corrupted files)
- [ ] Add tests for coordinate/dimension validation in create operations
- [ ] Test cross-platform path handling (Windows backslashes vs Unix forward slashes)
Add GitHub Action workflow for automated cargo-deny security audit on dependencies
The repo has multiple CI workflows (.github/workflows/ci.yml, test-report.yml, etc.) but there's no visible security scanning for vulnerable dependencies despite using 50+ external crates with deep dependency trees (cairo-rs, gtk4, nalgebra, etc.). Adding a cargo-deny workflow would catch known vulnerabilities in the supply chain and is a minimal setup that prevents security regressions.
- [ ] Create .github/workflows/security-audit.yml using cargo-deny action
- [ ] Create deny.toml in repo root with allow/deny lists for known problematic crates
- [ ] Configure workflow to run on PRs and scheduled weekly basis
- [ ] Ensure workflow fails the CI if high/critical vulnerabilities are found
- [ ] Reference existing security audit patterns from similar GTK4 Rust projects
🌿Good first issues
- Add unit tests for builders: crates/rnote-compose/src/builders/ has buildable.rs and shape constructors but no visible test files in the file list—add tests/builder_tests.rs covering ArrowBuilder, CoordSystem2DBuilder, and CoordSystem3DBuilder with property-based testing using proptest.
- Improve CLI export validation: crates/rnote-cli/src/export.rs and validators.rs lack documented export format constraints—write validation tests and expand validators.rs to cover SVG/PDF output format specs, boundary conditions, and example payloads with clear error messages.
- Document the .rnote file format: README mentions the format is unstable but provides no schema or specs—create docs/FILE_FORMAT.md describing the Flate2 compression structure, version negotiation, and serialization layout inferred from the codebase; include migration examples for breaking changes.
⭐Top contributors
Click to expand
Top contributors
- @flxzt — 51 commits
- @Doublonmousse — 13 commits
- @github-actions[bot] — 7 commits
- @weblate — 7 commits
- @Kneemund — 5 commits
📝Recent commits
Click to expand
Recent commits
99fd77f— feat(ci): update remaining workflow actions (flxzt)2ce2d02— chore: apply latest lints (flxzt)3d66083— feat(ci): update actions, pin 3rd party to rev (flxzt)8cac558— chore: bump version to v0.14.2 (flxzt)ea04446— i18n: Update traditional Chinese translation (github-actions[bot])c38e4f4— i18n: Translations update from Hosted Weblate (#1736) (weblate)388bbeb— fix: transparent stroke rendering (#1729) (Kneemund)02286b1— refactor: canvas widget adjustments (#1719) (Kneemund)7524655— fix: zooming with "alt+shift+drag" (#1742) (Kneemund)4cd0221— chore: bump version to v0.14.1 (flxzt)
🔒Security observations
Rnote demonstrates a reasonable security posture as a drawing application written in Rust with GTK4. The main concerns are: (1) use of git revision pinning instead of semantic versioning for hayro dependencies, (2) exact version pinning on librsvg that may delay security patches, (3) truncated dependency file preventing complete analysis, and (4) broad image format support increasing parser attack surface. The project uses the safer Rust language which mitigates memory safety vulnerabilities. Recommendations include implementing automated dependency scanning (cargo audit/deny), completing security analysis with full Cargo.toml, and generating SBOMs for transparency. No hardcoded secrets, SQL injection risks, or XSS vulnerabilities were identified in the visible codebase structure.
- Medium · Hardcoded Git Revision in Dependency —
Cargo.toml - workspace.dependencies (hayro and hayro-svg). The Cargo.toml specifies dependencies (hayro and hayro-svg) pinned to a specific git revision (56c62b2a25232d5407af8efe819c49ad46605979) without version constraints. This approach bypasses semantic versioning protections and makes it difficult to track security updates. If the upstream repository is compromised or the commit is removed, builds may fail unexpectedly. Fix: Consider using versioned releases from crates.io instead of git revisions. If git dependencies are necessary, document the reason and implement automated dependency scanning. Use git tags or branches with version constraints instead of raw revisions. - Medium · Librsvg Version Pinned Without Flexibility —
Cargo.toml - workspace.dependencies (librsvg = "=2.61"). The librsvg dependency is pinned to an exact version (=2.61) using equality constraints. While this ensures reproducibility, it prevents automatic security patches for minor/patch versions and may delay critical vulnerability fixes. Fix: Use semantic versioning constraints like "0.2.61" to allow patch updates, or implement automated dependency update checks. Regularly review and update librsvg versions to incorporate security fixes. - Low · Incomplete Dependency File Snapshot —
Cargo.toml - partial file content. The Cargo.toml file appears to be truncated in the provided content (cuts off at 'r'). This makes it impossible to perform complete security analysis of all transitive dependencies. There may be additional vulnerable dependencies not visible in this analysis. Fix: Provide complete Cargo.toml content. Run 'cargo audit' and 'cargo deny' to identify known vulnerabilities in the dependency tree. Implement automated dependency scanning in CI/CD pipeline. - Low · No Evidence of SBOM or Dependency Locking —
Repository root - absence of SBOM files. While Cargo.lock exists, there is no visible Software Bill of Materials (SBOM) or comprehensive dependency security documentation. This makes it harder for users and security auditors to understand the full attack surface. Fix: Generate and maintain SBOM files (e.g., cyclonedx-rust, cargo-sbom). Include dependency security scanning results in release notes. Document any pinned versions and their security rationale. - Low · Multiple Image Format Support Increases Attack Surface —
Cargo.toml - image and cairo-rs dependencies. The image crate is configured with multiple format handlers (png, bmp, gif, ico, jpeg, tiff) and the cairo-rs crate supports png, svg, and pdf. Each format parser represents potential attack surface for malformed file handling and buffer overflow vulnerabilities. Fix: Only enable image formats actually needed by the application. Implement strict input validation and file size limits for imported files. Use fuzzing tests for image import functionality. Consider sandboxing image processing operations. - Low · Cryptographic Dependencies May Need Review —
Cargo.toml - base64 dependency. The base64 dependency is included but no explicit cryptographic library (like 'ring', 'rustls', or 'openssl') is visible in the truncated Cargo.toml. This suggests base64 encoding/decoding may be used for security-critical operations without dedicated crypto libraries. Fix: If base64 is used for encoding sensitive data, ensure it's paired with proper encryption libraries. Never use base64 as a security mechanism. Implement proper authentication/encryption using established cryptographic libraries (e.g., rustls for TLS).
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.