Readust is a lightweight backend for Readest compatible clients. It replaces the original, larger backend stack with a small Rust service that provides Readest compatible APIs.
The service is built with Axum, PostgreSQL, SQLx, JWT authentication, and S3-compatible object storage. It is intended for private or self-hosted deployments where you want the Readest client experience without operating the full upstream backend.
- Readest-compatible auth endpoints under
/auth/v1 - Email and password signup/login with bcrypt password hashing
- JWT access tokens and refresh-token rotation
- Optional signup lockout for private deployments
- Sync API for books, book configs, reading progress, and notes
- Storage API for listing files, upload/download presigned URLs, deletion, purge, and usage stats
- PostgreSQL persistence with automatic SQLx migrations at startup
- S3-compatible object storage support, including MinIO, Cloudflare R2, Backblaze B2, and AWS S3
- Daily rotating application logs
- Rust 2024 toolchain
- PostgreSQL
- An S3-compatible bucket
Readust loads configuration from environment variables prefixed with READUST and from an optional TOML configuration file passed with --config.
The easiest way to start is to copy the example file and edit it:
cp config.example.toml config.tomlFor production, replace jwt_secret, database credentials, and S3 credentials. You can generate a JWT secret with:
openssl rand -hex 32For private deployments, set:
[application]
disable_signup = trueafter creating your first user.
Create a PostgreSQL database before starting the service:
CREATE DATABASE readust;readust runs migrations automatically on startup. The initial migration creates tables for users, tokens, books, book configs, notes, and files.
For SQLx tooling or offline checks, .example.env shows the expected DATABASE_URL format:
DATABASE_URL=postgres://readust:password@localhost:5432/readustStart the service with a config file:
cargo run -- --config config.tomlBuild a release binary:
cargo build --release
./target/release/readust --config config.tomlCreate a user:
curl -X POST http://localhost:8000/auth/v1/signup \
-H 'content-type: application/json' \
-d '{"email":"user@example.com","password":"password123"}'Login:
curl -X POST 'http://localhost:8000/auth/v1/token?grant_type=password' \
-H 'content-type: application/json' \
-d '{"email":"user@example.com","password":"password123"}'Get the current user:
curl http://localhost:8000/auth/v1/user \
-H 'authorization: Bearer <access-token>'Uploads return a presigned URL. The client uploads the object directly to S3 using that URL. File keys are stored with the authenticated user ID as a prefix:
<user-id>/<file-name>
Path inputs are restricted to normal relative path components. Absolute paths and parent-directory components are rejected.
Temporary uploads are currently not supported, and storage quota enforcement is not implemented yet. The API returns an effectively unlimited quota for compatibility.
Run checks and tests:
cargo testFormat code:
cargo fmtSee LICENSE.