| frontend | ||
| lib | ||
| scripts | ||
| .gitignore | ||
| config.example.yaml | ||
| Gemfile | ||
| Gemfile.lock | ||
| LICENSE | ||
| moneyler.rb | ||
| README.md | ||
| sample.xls | ||
| sample_2.xls | ||
Moneyler
Moneyler is a robust, self-hosted financial manager designed to import bank account movements from Excel (XLS) files and visualize them through a modern web interface. It combines a powerful CLI for data ingestion with a beautiful React-based dashboard for analytics.
🌟 Features
- Universal Import: Configurable parser engine that can handle XLS files from almost any bank by defining column mappings.
- Smart Balance Tracking: Automatically calculates and stores running balances for every movement, handling out-of-order insertions intelligently.
- Modern Dashboard: A responsive, dark-mode web interface built with React and Recharts.
- Interactive Charts: Dual-axis charts showing daily amounts and cumulative trends.
- Data Grid: Sortable, filterable table with server-side pagination.
- Multi-Account Support: Manage multiple bank accounts in a single instance.
- Lightweight: Powered by SQLite and Sinatra, ensuring low resource usage and easy backups.
🛠️ Tech Stack
- Backend: Ruby 3.x, Sinatra (API), ActiveRecord (ORM), SQLite3.
- Frontend: React 18, Vite, TypeScript, Recharts, Lucide Icons.
- CLI: Thor.
🚀 Installation & Setup
Prerequisites
- Ruby: Version 2.7 or higher.
- Node.js: Version 16 or higher (for building the frontend).
- SQLite3: Installed on your system.
1. Clone the Repository
git clone https://github.com/yourusername/moneyler.git
cd moneyler
2. Install Backend Dependencies
bundle install
3. Build the Frontend
The frontend is a React app located in frontend/. You need to build it so the Sinatra server can serve the static files from public/.
# Using the helper script
./scripts/frontend.sh install
./scripts/frontend.sh build
# OR manually
cd frontend
npm install
npm run build
cd ..
⚙️ Configuration
Moneyler uses a YAML configuration file to define your bank accounts and how to parse their Excel files.
-
Copy the example config:
cp config.example.yaml config.yaml -
Edit
config.yaml:accounts: "My Main Account": # The name used in CLI commands initial_amount: 1500.00 # Starting balance before any imports skip_first_row: true # Set to true if row 1 is headers columns: - date # Index 0: Transaction date - value_date # Index 1: Value date - dummy_negative # Index 2: Withdrawal column (if separate) - dummy_positive # Index 3: Deposit column (if separate) - currency # Index 4: Currency code (EUR, USD) - null # Index 5: Ignore this column - description # Index 6: Transaction descriptionMapping Types:
date: Date of transaction (DD/MM/YYYY).value_date: Value date of transaction.amount: Signed amount column (negative for expense, positive for income).dummy_negative: Column containing unsigned numbers for withdrawals (will be converted to negative).dummy_positive: Column containing unsigned numbers for deposits.currency: Currency string.description: Text description.null: Skip this column.
🖥️ Usage
Moneyler operates via a single executable script: moneyler.rb.
Importing Data
To import an XLS file into a specific account defined in your config:
# Syntax: ruby moneyler.rb import <FILE_PATH> <ACCOUNT_NAME>
ruby moneyler.rb import ~/Downloads/statement_jan_2024.xls "My Main Account"
The system will:
- Parse the file based on the account's column mapping.
- Insert new movements.
- Automatically recalculate the running balance for all affected movements.
Starting the Server
To view the dashboard:
ruby moneyler.rb server
By default, it listens on http://localhost:4567.
You can specify a different port:
ruby moneyler.rb server --port 8080
🐳 Docker Support
Moneyler works great with Docker. This is the easiest way to run the application without installing Ruby or Node.js on your host.
Quick Start with Docker Compose
-
Configure: Ensure you have
config.yamlset up (see Configuration section). -
Run:
docker-compose up -dThe application will be available at
http://localhost:4567.- The database is persisted in a docker volume
moneyler-datamounted at/app/datainside the container. - Your local
config.yamlis mounted into the container.
- The database is persisted in a docker volume
🏭 Production Deployment
To run Moneyler in a production environment (e.g., on a Raspberry Pi or VPS):
1. Reverse Proxy (Nginx)
It is recommended to run Moneyler behind Nginx for security and SSL termination.
server {
listen 80;
server_name money.yourdomain.com;
location / {
proxy_pass http://localhost:4567;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
2. Service Management (Systemd)
Create a systemd service to keep Moneyler running in the background.
File: /etc/systemd/system/moneyler.service
[Unit]
Description=Moneyler Web Server
After=network.target
[Service]
Type=simple
User=youruser
WorkingDirectory=/path/to/moneyler
ExecStart=/usr/bin/bundle exec ruby moneyler.rb server -p 4567
Restart=always
[Install]
WantedBy=multi-user.target
Enable and start:
sudo systemctl enable moneyler
sudo systemctl start moneyler
3. Database Backup
Your data lives in moneyler.db. Backing it up is as simple as copying this file.
Automated cron backup:
# Daily backup at 3 AM
0 3 * * * cp /path/to/moneyler/moneyler.db /path/to/backups/moneyler_$(date +\%F).db
👨💻 Development
To work on the frontend with hot-reloading:
- Start the Ruby backend (API):
ruby moneyler.rb server - In a separate terminal, start the Vite dev server:
(This is configured to proxy API requests to port 4567)./scripts/frontend.sh dev
📄 License
MIT License.