A local-first web application for piano enthusiasts to upload MIDI or MXL files, automatically convert them to sheet music (MXL and PDF formats) using MuseScore CLI, and manage/search their music library.
- MIDI/MXL Upload: Web interface for uploading
.mid/.midior.mxlfiles - Automatic Conversion: Convert MIDI → MXL → PDF or MXL → PDF (and optionally MIDI) using MuseScore CLI
- Library Management: Browse, search, and organize your sheet music collection
- PDF Preview: View sheet music directly in the browser
- File Downloads: Download PDF and MXL files
- Image OMR (Audiveris): Upload PNG/JPG images and convert to MusicXML when Audiveris is configured
- Local Storage: All files stored locally with JSON metadata
- No Database: File-based storage, no external dependencies
- Next.js 14 (App Router) with TypeScript
- Tailwind CSS for styling
- Lucide React for icons
- Formidable for file upload parsing
- fs-extra for filesystem operations
- MuseScore CLI for MIDI conversion
- Node.js 18+ and npm
- MuseScore installed on your system
- Windows: Install MuseScore 4 from musescore.org
- Linux:
sudo apt install musescoreor similar - macOS:
brew install musescoreor download from website
-
Clone and install
git clone <repository-url> cd midi-library-manager npm install
-
Configure environment
cp .env.local.example .env.local # Edit .env.local with your MuseScore path -
Start development server
npm run dev
-
Open browser Navigate to
http://localhost:3000
Create .env.local file with the following:
# MuseScore CLI executable path
MUSESCORE_PATH="C:\Program Files\MuseScore 4\bin\MuseScore4.exe" # Windows
# MUSESCORE_PATH="mscore" # Linux/macOS
# Audiveris OMR executable path (enables image OMR upload)
AUDIVERIS_PATH="C:\Program Files\Audiveris\Audiveris.exe" # Windows
# Expose MuseScore availability to client (controls PDF/MIDI buttons)
NEXT_PUBLIC_MUSESCORE_ENABLED=true
# Library storage directory (relative to project root)
LIBRARY_PATH="./library"
# Maximum upload size in bytes (default: 50MB)
MAX_UPLOAD_SIZE=52428800- Windows:
"C:\Program Files\MuseScore 4\bin\MuseScore4.exe" - Linux:
"mscore" - macOS:
"/Applications/MuseScore 4.app/Contents/MacOS/mscore"
midi-library-manager/
├── app/ # Next.js App Router
│ ├── api/ # API routes (upload, library, search, download)
│ ├── upload/ # Upload page
│ ├── library/ # Library page
│ ├── preview/[id]/ # PDF preview page
│ └── components/ # React components
├── lib/ # Core application logic
│ ├── storage.ts # Filesystem operations
│ ├── converter.ts # MuseScore CLI calls
│ ├── metadata.ts # meta.json handling
│ └── types.ts # TypeScript interfaces
├── library/ # Storage directory (created at runtime)
├── public/ # Static assets
└── ...config files
- Navigate to
/upload - Drag & drop or select a
.mid/.midior.mxlfile, or an image (.png/.jpg) if Audiveris is configured - Click "Upload & Convert"
- System will:
- For images: invoke Audiveris in batch mode to produce MusicXML (MXL/XML)
- Save files under a new UUID piece directory
- If MuseScore is available:
- For MIDI: convert to MXL then to PDF, and optionally to MIDI
- For MXL: convert to PDF and optionally to MIDI
- For OMR output (MXL/XML): convert to PDF and optionally to MIDI
- If MuseScore is not available: keep MXL/XML only; PDF/MIDI downloads are disabled
- Create metadata file
- Redirect to library
- View all pieces at
/library - Search by title, filename, or tags
- Click any piece to preview PDF
- Download PDF/MXL files
- Delete pieces
- Click any piece in the library
- PDF preview loads in browser
- Download buttons for PDF and MXL
npm run dev- Start development servernpm run build- Create production buildnpm start- Start production servernpm run lint- Run ESLint (if configured)
Each piece gets a unique folder in ./library/:
library/
├── {uuid}/
│ ├── original.mid # Uploaded MIDI file
│ ├── score.mxl # Generated MXL (MusicXML)
│ ├── score.pdf # Generated PDF sheet music
│ └── meta.json # Metadata (title, date, tags)
POST /api/upload- Upload and convert MIDI fileGET /api/library- List all piecesDELETE /api/library?pieceId={id}- Delete a pieceGET /api/search?q={query}- Search piecesGET /api/download?pieceId={id}&type={pdf|mxl|mid}- Download files
- Command not found: Ensure MuseScore is installed and path is correct in
.env.local - Conversion fails: Check MuseScore version supports CLI conversion
- Permission errors: Ensure MuseScore executable has execute permissions
- Upload fails: Check file size limit (
MAX_UPLOAD_SIZE) - Wrong file type: Only
.mid/.midifiles accepted - Storage full: Ensure disk space available
The application can be accessed from other devices on your local network (e.g., Android tablet, phone, other computers).
-
Start the development server (already configured to listen on all network interfaces):
npm run dev
-
Find your computer's local IP address:
- Windows: Run
ipconfigin Command Prompt and look for "IPv4 Address" - macOS/Linux: Run
ifconfigorip addrand look for your network interface IP
- Windows: Run
-
Access from other devices:
- Open a web browser on your Android tablet/other device
- Navigate to
http://[YOUR_LOCAL_IP]:3000(replace[YOUR_LOCAL_IP]with your actual IP) - Example:
http://192.168.1.100:3000
- Firewall: Ensure your firewall allows incoming connections on port 3000
- Port Configuration: Change port by setting
PORTenvironment variable (e.g.,PORT=8080 npm run dev) - Network: All devices must be on the same local network (same WiFi)
- Production: For permanent access, consider building and running in production mode with
npm run build && npm start
MIT
- MuseScore for the excellent music notation software
- Next.js for the React framework
- Tailwind CSS for styling