An app (installable as a service) that monitors a directory for Excalidraw files, moves them to a designated folder, and manages backups automatically.
Excalidraw saving is much simpler on chromium browsers due to the file-system API capabilities that they have, but unfortunately Firefox doesn't have those.
On chromium browsers, the browser simply overwrites the file, so all you really have to do is save the original file into the target folder, and every subsequent save will target and overwrite the original file.
Firefox (and its derivatives), however, create a new file with a version suffix instead of overwriting the save file of the previous one (i.e save.excalidraw, save(1).excalidraw, save(2).excalidraw
). I also didn't want to switch the browser-download-folder save path because it can become quite confusing, and sometimes just forget what the set path was.;
I made this application so I don't have to worry about that annoyance, and can backup my Excalidraw drawings with backup versions from my self-hosted instance to my Syncthing shared folder by simply pressing CTRL+S.
- Watches a downloads folder for new
.excalidraw
files - Automatically backs up existing files before overwriting
- Handles multiple file versions (e.g.,
drawing.excalidraw
,drawing(1).excalidraw
) - Timestamps backups based on last modified time
- Handles edge cases like simultaneous saves and duplicate timestamps
- Configurable via command-line arguments or config file
- Tracks statistics on files processed, backups created, and errors
- Rudimentary checks so you don't set the directory folders to the same path. It is bypassable, but it will likely break the application :)
- Bun - JavaScript runtime and package manager
- TypeScript - Language
- Oxlint - Linter
- Prettier - Code formatter
- Husky - Git hooks
- Systemd - Service management (Linux)
- Bun runtime installed
- Linux with systemd (for service installation; build manually if wanting to integrate on Windows)
-
Clone this repository or download the files, then install packages:
git clone https://github.com/Trifall/excalidraw-file-sync.git cd excalidraw-file-sync bun i
-
For installing for development or a custom build, see Development. For production and systemd service installation, see Production.
-
(Optional) Configure the application before installation:
You can prepare a configuration file by copying and editing the example:
cp config.json.example config.json nano config.json
The installer will detect and use this file automatically.
-
For running quickly in development:
# Using config file: bun dev --configPath config.json # Or specifying paths directly: bun dev --downloadsFolder=/path/to/downloads --syncFolder=/path/to/sync --backupsFolder=/path/to/backups
Install via Script (systemd service)
For a more streamlined installation, you can:
-
Create a
config.json
file in the project root before running the installer:cp config.json.example config.json nano config.json
-
Edit the paths according to your needs:
{ "downloadsFolder": "/path/to/downloads", "syncFolder": "/path/to/sync", "backupsFolder": "/path/to/backups" }
-
The installer will automatically detect and use this file, skipping the manual configuration prompts.
-
Make the installation script executable:
chmod +x install.sh
-
Run the installation script:
sudo ./install.sh
The script will:
- Check if Bun is installed
- Build the application
- Install it to
/opt/excalidraw-file-sync/
- Look for a
config.json
in the current directory, or ask for configuration values - Validate and create directories if needed (with your permission)
- Create a config file at
/etc/excalidraw-file-sync/config.json
- Set up and enable the systemd service
If an existing installation is detected, you'll be asked if you want to overwrite it.
You can configure the file watcher in three ways (in order of precedence):
-
Command-line arguments (manually running, forced overrides):
bun /opt/excalidraw-file-sync/dist/main.js --downloadsFolder=/path/to/downloads --syncFolder=/path/to/sync --backupsFolder=/path/to/backups
Or using a config file path:
bun /opt/excalidraw-file-sync/dist/main.js --configPath=/path/to/config.json
-
System configuration file (recommended, created during installation):
# Edit the system configuration sudo nano /etc/excalidraw-file-sync/config.json # After editing, restart the service sudo systemctl restart excalidraw-file-sync.service
The config file format:
{ "downloadsFolder": "/path/to/downloads", "syncFolder": "/path/to/sync", "backupsFolder": "/path/to/backups" }
-
Default locations (if no configuration is provided):
- Downloads folder:
~/Downloads
- Sync folder:
~/ExcalidrawSync
- Backups folder:
~/ExcalidrawSync/backups
- Downloads folder:
Once installed and running, the service will automatically:
- Monitor your downloads folder for
.excalidraw
files - When a new file is detected, it will:
- Back up any existing file with the same name in the sync folder
- Move the newest version to the sync folder
- Back up any intermediate versions
- Track statistics about operations performed
The service tracks the following statistics:
- Total files processed
- Number of backups created
- Errors encountered
These statistics are logged:
- Hourly (by default)
- When the service is shut down
- Can be viewed in the system service logs
Backups are stored in the format:
<backups_folder>/<filename_without_extension>/<filename_without_extension>-<timestamp>.excalidraw
If a file with the same timestamp already exists, it will use:
<backups_folder>/<filename_without_extension>/<filename_without_extension>-<timestamp>-<random_12_digit_number>.excalidraw
Check the service status:
sudo systemctl status excalidraw-file-sync
View logs (includes statistics):
journalctl -u excalidraw-file-sync
Check permissions:
# Ensure the service user has appropriate permissions to all folders
ls -la /path/to/downloads
ls -la /path/to/sync
ls -la /path/to/backups
To uninstall the service:
# Stop and disable the service
sudo systemctl stop excalidraw-file-sync
sudo systemctl disable excalidraw-file-sync
# Remove the service file
sudo rm /etc/systemd/system/excalidraw-file-sync.service
sudo systemctl daemon-reload
# Remove the app and config files
sudo rm -rf /opt/excalidraw-file-sync
sudo rm -rf /etc/excalidraw-file-sync
MIT