vnotex/vnote
A pleasant note-taking platform in native C++.
Single-maintainer risk — review before adopting
worst of 4 axescopyleft license (LGPL-3.0) — review compatibility; top contributor handles 97% 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 today
- ✓3 active contributors
- ✓LGPL-3.0 licensed
Show 5 more →Show less
- ✓CI configured
- ⚠Small team — 3 contributors active in recent commits
- ⚠Single-maintainer risk — top contributor 97% of recent commits
- ⚠LGPL-3.0 is copyleft — check downstream compatibility
- ⚠No test directory detected
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/vnotex/vnote)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/vnotex/vnote on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: vnotex/vnote
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/vnotex/vnote 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 today
- 3 active contributors
- LGPL-3.0 licensed
- CI configured
- ⚠ Small team — 3 contributors active in recent commits
- ⚠ Single-maintainer risk — top contributor 97% of recent commits
- ⚠ LGPL-3.0 is copyleft — check downstream compatibility
- ⚠ 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 vnotex/vnote
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/vnotex/vnote.
What it runs against: a local clone of vnotex/vnote — 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 vnotex/vnote | Confirms the artifact applies here, not a fork |
| 2 | License is still LGPL-3.0 | 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 ≤ 30 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of vnotex/vnote. If you don't
# have one yet, run these first:
#
# git clone https://github.com/vnotex/vnote.git
# cd vnote
#
# 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 vnotex/vnote and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "vnotex/vnote(\\.git)?\\b" \\
&& ok "origin remote is vnotex/vnote" \\
|| miss "origin remote is not vnotex/vnote (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(LGPL-3\\.0)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"LGPL-3\\.0\"" package.json 2>/dev/null) \\
&& ok "license is LGPL-3.0" \\
|| miss "license drift — was LGPL-3.0 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 "src/application.cpp" \\
&& ok "src/application.cpp" \\
|| miss "missing critical file: src/application.cpp"
test -f "src/controllers/markdowneditorcontroller.cpp" \\
&& ok "src/controllers/markdowneditorcontroller.cpp" \\
|| miss "missing critical file: src/controllers/markdowneditorcontroller.cpp"
test -f "src/core/buffer/buffer.cpp" \\
&& ok "src/core/buffer/buffer.cpp" \\
|| miss "missing critical file: src/core/buffer/buffer.cpp"
test -f "CMakeLists.txt" \\
&& ok "CMakeLists.txt" \\
|| miss "missing critical file: CMakeLists.txt"
test -f "src/controllers/viewareacontroller.cpp" \\
&& ok "src/controllers/viewareacontroller.cpp" \\
|| miss "missing critical file: src/controllers/viewareacontroller.cpp"
# 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/vnotex/vnote"
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
VNote is a Qt-based, open-source note-taking application built in native C++ with a focus on Markdown editing and note management. It provides a feature-rich editing experience with note organization capabilities, running natively on Linux, Windows, and macOS without web frameworks. Monolithic C++ application with modular architecture: src/ contains the main Qt application code; libs/ wraps third-party/internal libraries (including vtextedit submodule for editor); scripts/ provides OS-specific initialization and packaging; .github/workflows/ defines CI stages for each OS. Documentation in docs/ covers UI design principles and MVC patterns for components like NotebookExplorer.
👥Who it's for
Knowledge workers and Markdown enthusiasts who want a native, fast note-taking application with superior editing experience and note hierarchies, rather than browser-based or cloud-only alternatives. Includes both end-users and C++/Qt developers contributing to the codebase.
🌱Maturity & risk
Actively developed and production-ready: the repo shows continuous CI/CD pipelines for Windows, Linux, and macOS (.github/workflows/ci-*.yml), organized release infrastructure with continuous and stable builds, and structured development guidelines (AGENTS.md, CLAUDE.md). Recent evidence files (.sisyphus/evidence/) show ongoing testing and builds with regression verification.
Moderately low risk: the project has mature CI setup and clear governance (LGPL-3.0 license with SECURITY.md), but is primarily single-maintainer (vnotex org). Risk factors include the heavy Qt/C++ stack requiring specific build environment setup (CMake 56KB suggests complex configuration), and dependency on vtextedit submodule (.gitmodules) which could introduce version conflicts during development.
Active areas of work
Active development on buffer editing with autosave (plans/phase5-buffer-editing-autosave.md), NotebookExplorer2 MVC refactoring (docs/notebookexplorer2-mvc-plan.md), and stability improvements evidenced by recent regression testing and code-path verification in .sisyphus/evidence/. Continuous builds are maintained on the master branch.
🚀Get running
Clone and initialize the repo, then build with CMake:
git clone https://github.com/vnotex/vnote.git
cd vnote
bash scripts/init.sh # On Linux/macOS; or scripts\init.cmd on Windows
mkdir build && cd build
cmake ..
make # or cmake --build . on Windows
Daily commands: After building:
cd build
./vnote # On Linux/macOS
vnote.exe # On Windows (path may vary)
For development with hot reload, configure your CMake build with -DCMAKE_BUILD_TYPE=Debug and rebuild after source changes.
🗺️Map of the codebase
src/application.cpp— Main application entry point and lifecycle management for the Qt-based note-taking platform.src/controllers/markdowneditorcontroller.cpp— Core controller managing Markdown editing experience, the primary user interaction layer.src/core/buffer/buffer.cpp— Core buffer abstraction for note content management and editing state.CMakeLists.txt— Build configuration that defines Qt dependencies, platform-specific logic, and packaging.src/controllers/viewareacontroller.cpp— Manages the view area orchestration, routing between editor, preview, and other view modes.src/controllers/workspacewrapper.cpp— Wraps the workspace model, handling notebook and note persistence and navigation state.
🧩Components & responsibilities
- Application (src/application.cpp) (Qt QApplication, QMainWindow) — Bootstraps Qt, loads configuration, creates main window, handles lifecycle.
- Failure mode: App crashes on startup if Qt initialization fails or main window cannot be created.
- MarkdownEditorController (Qt QPlainTextEdit, QSyntaxHighlighter) — Manages the editor pane: text input, syntax highlighting, undo/redo, scroll synchronization.
- Failure mode: Large files cause UI lag; undo/redo stack exhausts memory; autosave races corrupt drafts.
- ViewAreaController (Qt QStackedWidget, QTabWidget) — Routes between editor, preview, mind-map, and PDF viewers; manages tab/pane layout.
- Failure mode: Switching views loses cursor position or unsaved state; cascade failures if child controller crashes.
- Buffer (Custom C++ data structure, Qt signals/slots) — In-memory representation of note content; tracks changes, undo/redo history, and sync-to-disk events.
- Failure mode: Out-of-memory on very large files; undo stack explosion; unsaved changes lost on crash.
- WorkspaceWrapper / Storage (Qt QFile, QDir, JSON serialization) — Abstracts notebook structure and file I/O; reads/writes .md files and metadata to disk.
- Failure mode: Disk full blocks autosave; file permissions denied; corrupted metadata breaks notebook index.
- MarkdownViewWindow (Qt WebEngineView or QTextBrowser, Markdown-to-HTML converter) — Renders Markdown to HTML for live preview; may use Qt WebEngine or native rendering.
- Failure mode: Slow rendering on long notes; WebEngine crashes
🛠️How to make changes
Add a new note view type (e.g., new viewer window)
- Create a new controller class inheriting from viewareacontroller patterns in src/controllers/ (
src/controllers/mynewviewwindowcontroller.h) - Implement the view logic and register in ViewAreaController::createNewViewWindow() (
src/controllers/viewareacontroller.cpp) - Wire the controller to the toolbar/menu in markdowneditorcontroller (
src/controllers/markdowneditorcontroller.cpp)
Add a new notebook backend or storage format
- Create a new folder under src/core/ with your storage abstraction (e.g., src/core/notebook/) (
src/core/notebook/mynotebookbackend.h) - Implement load/save serialization methods matching the buffer interface (
src/core/notebook/mynotebookbackend.cpp) - Register the backend in WorkspaceWrapper or a factory function (
src/controllers/workspacewrapper.cpp) - Add import logic in opennotebookcontroller if supporting legacy formats (
src/controllers/opennotebookcontroller.cpp)
Add a new toolbar action or menu item
- Define the action in markdowneditorcontroller (e.g., m_actionMyFeature) (
src/controllers/markdowneditorcontroller.h) - Implement the slot and wire it to a controller method (
src/controllers/markdowneditorcontroller.cpp) - Register the action in the toolbar or menu setup function (
src/controllers/markdowneditorcontroller.cpp)
🔧Why these technologies
- Qt 5/6 (C++) — Cross-platform GUI framework with native look-and-feel on Windows, macOS, and Linux; built-in Markdown editing and rich text capabilities.
- CMake build system — Portable multi-platform build configuration with Qt toolchain integration and packaging support for three OSes.
- Markdown as primary format — Human-readable, version-control-friendly note format; enables future support for multiple formats and integration with static site generators.
- MVC controller pattern — Separation of concerns: UI orchestration (controllers) decoupled from data models and rendering, enabling independent testing and reuse.
⚖️Trade-offs already made
-
Native C++ + Qt instead of Electron/web-based
- Why: Lower memory footprint, faster startup, native platform integration (menubar, system tray, file associations).
- Consequence: Larger development surface area; must maintain platform-specific code paths for Windows, macOS, Linux.
-
Local-first storage (disk-based notebooks) rather than cloud-sync
- Why: Privacy, offline-first experience, no authentication or server dependency.
- Consequence: Multi-device sync requires external tools (Git, cloud storage providers); no real-time collaboration.
-
Monolithic single-window application with multiple view modes
- Why: Simplified state management, unified workspace context.
- Consequence: Cannot easily split editing and preview into separate windows or arrange multiple notes side-by-side.
🚫Non-goals (don't propose these)
- Cloud synchronization or real-time collaboration (local-first only)
- Authentication or user account management
- Web-based or mobile versions (desktop only)
- Database backend (file-system based storage)
🪤Traps & gotchas
- Must run
scripts/init.shorscripts/init.cmdbefore first build—without it, vtextedit submodule is missing and CMake will fail. 2. Qt development headers and CMake 3.x+ are required; build will silently fail if Qt is not in PATH or CMAKE_PREFIX_PATH. 3. Pre-commit hook in .git/hooks/ (installed by init script) runs clang-format and blocks commits that violate .clang-format; reformat withclang-format -i <file>before retry. 4. Windows builds require Visual Studio 2019+ or MinGW; macOS builds assume Xcode toolchain; Linux requires build-essentials or equivalent. 5. CI workflows show platform-specific Qt versions and paths (e.g., macOS uses homebrew paths)—local builds may differ.
🏗️Architecture
💡Concepts to learn
- Qt Signal-Slot Mechanism — VNote's entire UI responsiveness and event handling relies on Qt's signal-slot pattern rather than traditional callbacks; understanding this is essential for modifying UI logic or adding event handlers
- Model-View-Controller (MVC) Pattern — NotebookExplorer2 is actively being refactored to explicit MVC (docs/notebookexplorer2-mvc-plan.md), so new contributors must understand how Models, Views, and Controllers interact in the codebase
- Git Submodules — VNote uses vtextedit as a submodule (.gitmodules); cloning without
--recursiveor failing to runscripts/init.shleaves the project in a broken state, making submodule lifecycle management critical knowledge - CMake Build System — CMakeLists.txt files orchestrate compilation across platforms (Linux, macOS, Windows), define compiler flags, Qt dependencies, and packaging rules; changes to build behavior must go through CMake
- Qt WebEngine — VNote uses QtWebEngine for rendering content (likely Markdown HTML previews); understanding its sandboxing, bridge communication, and asset loading is needed for preview/export features
- Markdown Parsing and AST Traversal — VNote's core feature is Markdown editing; the codebase must parse Markdown into an AST for syntax highlighting, outlining, and preview generation—this is likely in vtextedit submodule
- Cross-Platform Code Formatting via Clang-Format — Pre-commit hooks automatically enforce .clang-format rules; violating style blocks commits, so understanding clang-format configuration and how to fix formatting is a day-one requirement
🔗Related repos
obsidian-md/obsidian-releases— Direct competitor in note-taking space; Obsidian is closed-source but dominates the Markdown note market, making it the primary UX/feature benchmark for VNotejoplinapp/joplin— Open-source note-taking app with Markdown support and multi-platform presence; shares similar goals but uses Electron/Node.js instead of native Qtnotable/notable— Markdown note-taking application with similar positioning; demonstrates alternative architectural choices (Electron-based) for the same problem domainvnotex/vtextedit— Critical dependency of VNote (included as git submodule in .gitmodules); the actual editor implementation that VNote shells aroundqt/qt-creator— Ecosystem companion: Qt Creator IDE used for VNote development and debugging; shares the same Qt framework and build tooling
🪄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 unit tests for src/controllers/ modules
The controllers directory (attachmentcontroller, exportcontroller, importfoldercontroller, markdowneditorcontroller, markdownviewwindowcontroller) lacks visible test coverage. Given VNote's focus on pleasant editing experience, controller logic around attachment handling, markdown editing, and export/import functionality should have dedicated unit tests to prevent regressions.
- [ ] Create tests/controllers/ directory structure mirroring src/controllers/
- [ ] Add unit tests for attachmentcontroller.cpp covering attachment lifecycle (add, remove, validate)
- [ ] Add unit tests for exportcontroller.cpp covering different export formats and error handling
- [ ] Add unit tests for markdowneditorcontroller.cpp covering editor state management
- [ ] Integrate tests into CMakeLists.txt build configuration
- [ ] Update CI workflows (ci-linux.yml, ci-macos.yml, ci-win.yml) to run controller tests
Document the MVC architecture and controller patterns in src/controllers/AGENTS.md
The src/controllers/AGENTS.md file exists but the docs/notebookexplorer2-mvc-plan.md suggests ongoing MVC refactoring. New contributors need clear documentation on the controller architecture patterns used in markdowneditorcontroller, markdownviewwindowcontroller, and other controllers to make effective contributions.
- [ ] Expand src/controllers/AGENTS.md with architecture overview explaining the MVC separation
- [ ] Document the responsibility boundaries between controller classes (e.g., what markdowneditorcontroller vs markdownviewwindowcontroller handles)
- [ ] Add code examples showing proper signal/slot usage patterns in controllers
- [ ] Reference the notebookexplorer2-mvc-plan.md and explain which parts are completed vs in-progress
- [ ] Include guidelines for adding new controllers
Add cross-platform CI validation for package building in GitHub Actions
The file structure shows Packaging.cmake, CPackLinuxDeployQt.cmake.in, CPackMacDeployQt.cmake.in, and wix packaging setup (wix_banner.png, wix_dialog.png), but the existing CI workflows (ci-linux.yml, ci-macos.yml, ci-win.yml) don't appear to validate actual package generation. This creates risk of packaging regressions going undetected.
- [ ] Review and update ci-linux.yml to add AppImage/deb package build verification step
- [ ] Review and update ci-macos.yml to add DMG/PKG package build verification step
- [ ] Review and update ci-win.yml to add NSIS/WiX package build verification using scripts/pack-win.ps1
- [ ] Add artifact upload steps to store built packages for inspection
- [ ] Document package build requirements in docs/ or README
🌿Good first issues
- Add unit tests for the NotebookExplorer2 MVC refactoring (docs/notebookexplorer2-mvc-plan.md mentions the pattern but test coverage is not visible in src/)—start by examining the Model, View, and Controller classes and writing test stubs in a new tests/ directory following the CI patterns in .github/workflows/.
- Document the buffer editing autosave feature (plans/phase5-buffer-editing-autosave.md) by adding architecture and user-facing docs to docs/—this feature is active but lacks corresponding documentation visible in the repo.
- Expand clang-format pre-commit hook in scripts/init.sh to validate commit messages (e.g., enforce prefix like 'feat:', 'fix:') and add a corresponding GitHub workflow to catch non-conforming PRs early, reducing CI friction.
⭐Top contributors
Click to expand
Top contributors
📝Recent commits
Click to expand
Recent commits
7cd564b— style(settings): remove trailing colons from option labels (tamlok)6924113— ui(settings): use dedicated apply icon instead of reusing save icon (tamlok)a6c5666— feat(ui): add system program settings row and dispatch (tamlok)b33863b— feat(core): add built-in system external program with lowest priority (tamlok)31ab736— try to copy necessary extra data even version is not changed (tamlok)dd344f2— fix(editor): use scrollable text area for paste info dialog (tamlok)c53616b— fix(editor): remove incorrect same-directory check for image paste (tamlok)38458c5— chore: update vtextedit submodule with copy-interception signal (tamlok)9403419— test(clipboard): add tests for clipboard resource-aware paste (tamlok)3069bde— feat(editor): add post-paste info dialog for copied images (tamlok)
🔒Security observations
VNote demonstrates reasonable baseline security practices for an open-source C++ application with a defined security policy and public disclosure process. However, key areas for improvement include: (1) clarifying vulnerability response timelines and SLAs, (2) reducing friction in the disclosure process, (3) implementing automated security scanning in CI/CD pipelines, (4) establishing formal dependency management and SBOM practices, and (5) protecting maintainer contact information. The project would benefit from more robust security tooling in the build pipeline and a more inclusive vulnerability disclosure approach to encourage responsible reporting from the security research community.
- Medium · Incomplete Security Policy - No Formal SLA —
SECURITY.md. The SECURITY.md policy only supports the latest version with security updates, which is a very narrow support window. No clear SLA or timeline is defined for vulnerability response and patch deployment. Fix: Establish a clear vulnerability disclosure SLA (e.g., 30-90 days to patch), define supported versions with overlapping support periods, and document the security update process timeline. - Medium · Excessive PoC Requirement for Vulnerability Reporting —
SECURITY.md. The security policy requires reporters to provide a full proof-of-concept before any vulnerability consideration. This creates friction in responsible disclosure and may prevent initial triage of potentially critical vulnerabilities. Fix: Accept vulnerability reports with severity assessment before requiring full PoC. Allow staged disclosure where initial report triggers triage, then PoC is developed collaboratively. - Low · No Bug Bounty Program —
SECURITY.md. The project explicitly states it does not offer bounties for security discoveries. While not inherently a vulnerability, this may reduce incentive for security researcher participation in responsible disclosure. Fix: Consider implementing a modest bug bounty program or at minimum offer public recognition/credit to incentivize responsible disclosure from the security community. - Low · Limited Visibility into Dependency Management —
CMakeLists.txt, .gitmodules. No package lockfiles (package-lock.json, yarn.lock, etc.) or dependency manifests are visible in the provided file structure. For a C++ project, this is less critical than web projects, but CMakeLists.txt dependencies should be carefully reviewed. Fix: Ensure all external dependencies (especially from .gitmodules) are pinned to specific versions, maintain a software bill of materials (SBOM), and regularly audit dependencies for known vulnerabilities using tools like OWASP Dependency-Check. - Low · No Evidence of Dependency Scanning in CI/CD —
.github/workflows/. The GitHub Actions workflows (ci-linux.yml, ci-macos.yml, ci-win.yml) are not fully visible, but no mention of automated dependency scanning or security checks is apparent in the file structure. Fix: Integrate automated security scanning into CI/CD pipeline: add SAST tools (e.g., Clang Static Analyzer, SonarQube), dependency vulnerability scanning (e.g., Dependabot, Snyk), and DAST where applicable. - Low · Sensitive Contact Information Exposed —
SECURITY.md. Support email (tamlokveer@gmail.com) is directly embedded in SECURITY.md without additional protection mechanisms, potentially exposing maintainer to targeted spam or social engineering. Fix: Consider using a security-specific email alias or contact form, implement rate limiting on vulnerability report submissions, or use a platform like Hackerone/Bugcrowd.
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.