A custom, lightweight, 100% compatible Joplin Sync Server written in Go.
The official Joplin app is named in honor of the famous composer and pianist, Scott Joplin. This custom server is named Syncopation as a play on words: it syncs your notes, and syncopation is a core musical concept that drives the ragtime rhythm Scott Joplin is known for.
- 100% Joplin Client Compatibility: Seamlessly works with official Joplin Desktop, Mobile, and CLI clients.
- End-to-End Encryption (E2EE): Fully supports transparent syncing of encrypted notes.
- Efficient Sync Engine: Handles delta syncs, sync locks, concurrency control, and batch operations.
- Lightweight & Fast: Built in Go, utilizing a single static binary and minimal memory footprint.
- Admin Web UI: Built-in administration panel using HTMX.
- Simple Deployment: Single Docker container with SQLite and Local Disk storage. No external database required.
- Backend: Go (Standard Library
net/http) - Database: SQLite (via
sqlc) - Storage: Local Filesystem
- Admin UI: Go
html/template+ HTMX
This is the recommended way to run Syncopation on your home server, NAS, or VPS.
Create a docker-compose.yml file:
services:
syncopation:
image: ghcr.io/jberlyn/syncopation:latest
container_name: syncopation
restart: unless-stopped
ports:
- "22300:22300"
volumes:
- syncopation-data:/app/data
volumes:
syncopation-data:The server stores both the SQLite database (syncopation.sqlite) and all physical note attachments inside the /app/data directory within the container.
It is crucial that you persist this directory.
- Named Volume (Example above): Best for easy management by Docker.
- Bind Mount: If you prefer storing the data in a specific folder on your host (e.g.,
- ./my-syncopation-data:/app/data), ensure the container has write permissions to that directory.
Start the server:
docker compose up -dVisit the Admin UI at http://localhost:22300/admin in your browser.
Since this is a fresh install, you will be presented with a Zero-User Onboarding Flow to create your initial administrator account.
It is highly recommended to place Syncopation behind a reverse proxy (like Caddy, Nginx, or Traefik) to provide HTTPS/TLS.
Important: Ensure your reverse proxy is configured to allow large request bodies (Joplin can upload large attachments) and passes standard headers.
- Nginx: Add
client_max_body_size 100M;to your server block. - Caddy: Automatically handles large bodies and SSL. A simple Caddyfile:
syncopation.yourdomain.com { reverse_proxy localhost:22300 }
- Open Joplin and go to Options > Synchronization.
- Set Sync target to Joplin Server.
- Joplin Server URL: Your server's URL (e.g.,
https://joplin.yourdomain.comorhttp://your-server-ip:22300). - Joplin Server email: The email of the account you created.
- Joplin Server password: Your password.
- Click "Check synchronization configuration".
- Go 1.25+
sqlc(for generating DB queries)
Note: Syncopation uses the pure-Go modernc.org/sqlite driver, so CGO is not required. This makes the project extremely easy to build and cross-compile!
go build -o syncopation .
./syncopationSyncopation uses Go's standard testing package.
- Unit & Integration Tests: Run with
go test ./... - E2E Tests: Use
net/http/httptestviago test ./api/...
This project was built with the assistance of AI tooling such as Antigravity following a Research, Plan, Implement strategy.
This software is licensed under the PolyForm Noncommercial License 1.0.0. You may use, modify, and distribute this software for any non-commercial purpose (personal use, hobbies, research, etc.).
If you wish to use this software for commercial purposes (including offering it as a paid service), you must obtain explicit permission or a commercial license from the author. For full license terms, please see the LICENSE file.