Efficient and minimal collaborative code editor, self-hosted, no database required
You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
Eric Zhang 14dde3c283 Update README to reflect new Fly.io hosting 9 months ago
.github/workflows Only log in to DockerHub on `push` event 2 years ago
public Update dependencies and switch build to Vite (#30) 2 years ago
rustpad-server Improve persistence logic (#55) 1 year ago
rustpad-wasm Update frontend dependencies and clippy lints (#33) 2 years ago
src Add additional support for Monaco basic languages (#35) 2 years ago
.dockerignore Update dependencies and switch build to Vite (#30) 2 years ago
.editorconfig Initial commit 2 years ago
.env Allow configuring the number of days to expire documents (#18) 2 years ago
.gitignore Update dependencies and switch build to Vite (#30) 2 years ago
.prettierignore Update dependencies and switch build to Vite (#30) 2 years ago
.prettierrc Initial commit 2 years ago
Cargo.lock Improve persistence logic (#55) 1 year ago
Cargo.toml Rename `rustpad-core` to `rustpad-wasm`, add Serde 2 years ago
Dockerfile Add multi-platform build support for linux/arm64 (#32) 2 years ago
LICENSE Add MIT license 2 years ago
README.md Update README to reflect new Fly.io hosting 9 months ago
index.html Add og:title and og:description meta tags (#59) 10 months ago
package-lock.json Update frontend dependencies and clippy lints (#33) 2 years ago
package.json Update frontend dependencies and clippy lints (#33) 2 years ago
tsconfig.json Set up WebAssembly compilation and loading 2 years ago
vite.config.js Update dependencies and switch build to Vite (#30) 2 years ago

README.md

Rustpad

Docker Pulls Docker Image Size GitHub Workflow Status

Rustpad is an efficient and minimal open-source collaborative text editor based on the operational transformation algorithm. It lets users collaborate in real time while writing code in their browser. Rustpad is completely self-hosted and fits in a tiny Docker image, no database required.


rustpad.io

The server is written in Rust using the warp web server framework and the operational-transform library. We use wasm-bindgen to compile text operation logic to WebAssembly code, which runs in the browser. The frontend is written in TypeScript using React and interfaces with Monaco, the text editor that powers VS Code.

Architecturally, client-side code communicates via WebSocket with a central server that stores in-memory data structures. This makes the editor very fast, allows us to avoid provisioning a database, and makes testing much easier. The tradeoff is that documents are transient and lost between server restarts, or after 24 hours of inactivity.

Development setup

To run this application, you need to install Rust, wasm-pack, and Node.js. Then, build the WebAssembly portion of the app:

wasm-pack build --target web rustpad-wasm

When that is complete, you can install dependencies for the frontend React application:

npm install

Next, compile and run the backend web server:

cargo run

While the backend is running, open another shell and run the following command to start the frontend portion.

npm run dev

This command will open a browser window to http://localhost:3000, with hot reloading on changes.

Testing

To run integration tests for the server, use the standard cargo test command. For the WebAssembly component, you can run tests in a headless browser with

wasm-pack test --chrome --headless rustpad-wasm

Configuration

Although the default behavior of Rustpad is to store documents solely in memory and collect garbage after 24 hours of inactivity, this can be configured by setting the appropriate variables. The application server looks for the following environment variables on startup:

  • EXPIRY_DAYS: An integer corresponding to the number of days that inactive documents are kept in memory before being garbage collected by the server (default 1 day).
  • SQLITE_URI: A SQLite connection string used for persistence. If provided, Rustpad will snapshot document contents to a local file, which enables them to be retained between server restarts and after their in-memory data structures expire. (When deploying a Docker container, this should point to the path of a mounted volume.)
  • PORT: Which local port to listen for HTTP connections on (defaults to 3030).
  • RUST_LOG: Directives that control application logging, see the env_logger docs for more information.

Deployment

Rustpad is distributed as a single 6 MB Docker image, which is built automatically from the Dockerfile in this repository. You can pull the latest version of this image from Docker Hub. It has multi-platform support for linux/amd64 and linux/arm64.

docker pull ekzhang/rustpad

(You can also manually build this image with docker build -t rustpad . in the project root directory.) To run locally, execute the following command, then open http://localhost:3030 in your browser.

docker run --rm -dp 3030:3030 ekzhang/rustpad

We deploy a public instance of this image using Fly.io.

In the media


All code is licensed under the MIT license.