A desktop app for songwriters to write, version, and compare lyrics.
Lyra keeps every draft of your lyrics as immutable snapshots, lets you diff any two versions at the character level, and stores everything in plain files you own. No cloud, no accounts, no lock-in.
- Vault — point Lyra at any folder and it becomes your song library.
- Sections — songs are built from ordered, labeled sections (Verse, Chorus, Bridge, etc.) that you can drag to reorder.
- Snapshots — save a named point-in-time capture of your song at any moment, like a git commit for lyrics.
- Diffs — compare any two snapshots, or a snapshot against your current draft, with character-level highlighting.
- Comments — annotate any section with notes, optionally pinned to a specific snapshot.
- Autosave — changes are saved to disk automatically after 2 seconds of inactivity.
- Export — plain-text export of any song, with optional version history appended.
- File association — double-click a
.lyrfile in your OS to open it directly in Lyra.
The docs/user/ folder contains the full user guide:
- Getting Started
- Songs and Sections
- Snapshots
- Comparing Versions
- Comments
- Find and Replace
- Exporting
- Keyboard Shortcuts
You don't need to build from source to use Lyra. Pre-built installers are available for Windows, macOS, and Linux.
- Go to the Releases page.
- Open the latest release and expand the Assets section.
- Download the installer for your operating system:
- Windows:
.msi(recommended) or.exesetup installer - macOS:
.dmgdisk image - Linux:
.AppImage(universal),.deb(Debian/Ubuntu), or.rpm(Fedora/RHEL)
- Windows:
- Run the installer and follow the prompts.
Once installed, open Lyra, point it at a folder to use as your vault, and start writing.
| Requirement | Version | Notes |
|---|---|---|
| Node.js | ≥ 20 | For the frontend build |
| Rust | stable | For the Tauri backend |
| Tauri system deps | — | Platform-specific (see link) |
| WebView2 | — | Windows only, usually pre-installed on Win 10/11 |
| WebKitGTK + other libs | — | Linux only, install via your distro's package manager (see Tauri prerequisites link above) |
Follow the Tauri v2 prerequisites guide for your OS before continuing.
git clone https://github.com/GabrielBG0/lyra.git
cd lyra
npm installnpm run tauri devThis starts the Vite dev server on port 1420 with hot module replacement, then launches the Tauri window on top of it. Changes to React files reload instantly; changes to Rust files trigger a Rust recompile.
npm run tauri buildProduces a native installer for your current platform in src-tauri/target/release/bundle/. On macOS this is a .dmg; on Windows an .msi and .exe installer; on Linux an .AppImage, .deb, and .rpm.
lyra/
├── src/ # React frontend (TypeScript + Vite)
│ ├── components/ # UI components, organized by feature
│ ├── hooks/ # Custom React hooks (autosave, shortcuts, vault, etc.)
│ ├── lib/ # Typed IPC bindings, domain types, utilities
│ ├── stores/ # Zustand state stores
│ └── styles/ # Global CSS, design tokens (OKLCH color system)
│
├── src-tauri/ # Rust backend
│ ├── src/
│ │ ├── commands/ # Tauri command handlers (thin IPC layer)
│ │ ├── core/ # Domain logic: file I/O, diff, vault scanning, index
│ │ └── models/ # Serde structs mirroring the TypeScript types
│ └── migrations/ # SQLite migration files
│
├── CLAUDE.md # AI assistant instructions for this codebase
├── project_overview.md # Full architecture reference
└── style_guidelines.md # Design system and UI conventions
A vault is any folder on your disk. Lyra scans it for .lyr files on startup and keeps a SQLite index at .lyrindex/index.db for fast listing and search. The index is a cache — it can always be rebuilt from the files themselves. If you add, remove, or sync .lyr files while the app is open (e.g. via Dropbox), the file watcher picks up the changes automatically.
Each song is a single .lyr file, which is a ZIP archive with a predictable structure:
my-song.lyr (ZIP)
├── meta.json # format version gate
├── song.toml # title, status, key, BPM, tags
├── sections/
│ ├── 01HXKM....toml # one file per section, identified by ULID
│ └── 01HXKM....toml
├── snapshots/
│ └── 01HXKM....json # append-only, immutable snapshot files
└── comments.toml # all section annotations
All writes go through a write-to-temp-then-atomic-rename pattern so a crash mid-write never corrupts your file. Snapshots are append-only and never modified after creation.
Because .lyr files are just ZIPs, you can inspect them with any archive tool, version them with git, or move them between machines without any export step.
| Shortcut | Action |
|---|---|
Ctrl/⌘ + N |
New song |
Ctrl/⌘ + S |
Save |
Ctrl/⌘ + Shift + S |
Save a snapshot (take) |
Ctrl/⌘ + W |
Close song |
Ctrl/⌘ + B |
Toggle sidebar |
Ctrl/⌘ + H |
Toggle history bar |
Ctrl/⌘ + Z |
Undo |
Ctrl/⌘ + Shift + Z |
Redo |
Ctrl/⌘ + C |
Copy focused section |
Ctrl/⌘ + X |
Cut focused section |
Ctrl/⌘ + V |
Paste section |
Ctrl/⌘ + , |
Preferences |
Esc |
Close modal / exit diff / cancel edit |
A full shortcut reference is available inside the app under Help > Keyboard Shortcuts.
| Layer | Technology |
|---|---|
| Desktop shell | Tauri 2 |
| Frontend | React 19, TypeScript, Vite 7 |
| Styling | Tailwind CSS 4, OKLCH design tokens |
| State | Zustand 5 |
| Backend | Rust, Tokio |
| Database | SQLite via sqlx 0.7 (index cache only) |
| File format | ZIP (zip crate) + TOML + JSON |
| Diffing | similar crate (character-level) |
| Icons | Lucide React |
MIT