Rustpad is an efficient and minimal collaborative code editor, self-hosted, no database required

Overview

Rustpad

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 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 start

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 rustpad-wasm --chrome --headless

Deployment

Rustpad is distributed as a single 12 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.

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 DigitalOcean App Platform.


All code is licensed under the MIT license.
Comments
  • arm64 (aarch64) Support

    arm64 (aarch64) Support

    Hey!

    Given the technologies used in this project, and that I already run code-server just fine on it, this should be running just fine on an Raspberry-Pi (at least versions >=3).

    With that in mind, and seeing that the official Docker-Image just works on amd64, I cloned the repository and tried around a bit.

    Btw, from what I've seen its a nice code-basis. The tsx-Code (the JS part of the frontend) could use a few folders but otherwise real nice, insofar as I'm a good judge of that.

    Well, I saw some good and some problematic stuff, but the problematic stuff should be possible to work around. The good stuff is that rustpad-server builds just fine.

    The problem is that wasm-pack seems to REALLY not like arm64. I was able to fix some issues by installing wasm-pack via cargo install instead of the install script, and switching from rust:alpine with musl to the debian based rust:latest. After this (and loong build-times, even on my raspi 4 with an SSD, but thats Rust) it failed because of another binary wasm-pack looking for AFTER most of the compilation of the project - not wasm-pack but your rustpad-server-, wasm-opt. Now, I could fix that too, and I think it should be fine after this - I guess this does some kind of link-time-optimization? -, but I'm unsure what influence that might have on performance, and given how long it took to get here to start, and that this should be avoidable (see later), I think it would be great to solve this on an project-level.

    Because given that the purpose of that step is to generate some architecture-independent wasm-"binary", and Rusts excellent cross-compilation support, I'm sure there is a way to just create

    1. the architecture-independent wasm, js etc artifacts
    2. and the architecture-dependent binary

    In your pipeline and either at least distribute these artifacts, or better yet find a way to make the pipeline build an arm64 docker-image that also gets distributed via docker-hub.

    After all once you have these artifacts all thats left to do is copy these into the image, switch the user and declare the entrypoint, all that in a simple "scratch" container.

    Now, the reason I post this here, and don't just do it and make a PR, is that

    1. I have no experience with docker-multiarch etc, so if someone has some comments on this/wants to help I'd love that
    2. This would influence the pipeline quite a bit, and I wanted to check with you that such changes would even be accepted/ generally hear what your feeling is about all this.

    Sam.

    opened by 9SMTM6 8
  • State Persistence for volatile deployments

    State Persistence for volatile deployments

    It appears that the current implementation keeps the state table in volatile memory (RAM) rather than committing it to disk. As such, deploying this in a scenario where the service's lifetime is not guaranteed (container orchestration, e.g. kubernetes) the state would be lost in an eviction scenario.

    It would be nice if there was a way to offload the state table into a somewhat more persistent datastore or use something like sqlite with a pvc in kubernetes to help maintain state.

    opened by PeterGrace 8
  • Add upload and download functionality

    Add upload and download functionality

    Would solve #36. Most things seems to work as intended, very sparse detection of languages for now, a few questions are open, and I think the amount of code in App.tsx asks for a refactor, moving out code.

    opened by 9SMTM6 6
  • Third-party websocket client

    Third-party websocket client

    I would love to use rustpad for my hardware live coding project. Is it possible to connect a third-party client via WebSocket to rustpad? If you can point me to any examples or resources it would be great.

    Thank you.

    opened by curiouswala 6
  • Changing hour and day values for cleanup

    Changing hour and day values for cleanup

    Hey!

    I saw that rustpad has fixed values for the cleanup intervals:

    https://github.com/ekzhang/rustpad/blob/64d0b632ac72143c4e94fce1ecaf5db94bb90547/rustpad-server/src/lib.rs#L82-L83

    I think it would be nice to make them configurable via dotenv or any other solution. Do you think it's applicable? If so, I'd like to submit a PR.

    opened by orhun 6
  • Mobile Responsive support?

    Mobile Responsive support?

    Hi, I really love your application because it's simplicity. The application works great on large screen devices like computers and tablets. However, when I open it using my phone (iPhone 7), the left panel seem to cover all the screen that users like me can not see the text content. Do you have any plan to add Mobile Responsive in the future?

    Thank you and stay safe!

    opened by hzhoanglee 4
  • Ease-of-use: Upload and download of Files

    Ease-of-use: Upload and download of Files

    Hey, I've used this Application a bit now, and I've got a few ideas.

    As my Exams are coming up I will not be able to contribute much to these, but I wanted to record them here nonetheless.

    First there were 2 things that I wondered about, that were already addressed, or likely out of scope, and that are persistent files/sessions (so it can work as a kind of pastebin) (it seems #6 addresses that), and multi-file workspaces are probably widely out of scope.

    But I had another thought that should not be too hard to implement, and IMO would significantly increase ergonomics.

    "File"-Upload and Download does not seem to be implemented, unless I missed it. The way I imagine it, is that one would be able to "Upload" a text-file via drag and drop, this would just paste in the content, and ideally also determine the Programming-language via file-extension. To download, I've seen websites that intercept the Ctrl-S command to save files (eg drawio). I'm not actually sure how they do it, but it appears there is a way, and that would be ideal IMAO.

    Thanks, Sam.

    enhancement good first issue 
    opened by 9SMTM6 4
  • Read-only mode?

    Read-only mode?

    Not a bug, but a feature request. I LOVE the editor abilities of this, but would like the option to share it as read-only. I suppose an approach to having this work so that the author can still make changes, is perhaps a new link that references the original "tag", but is one that, when de-referenced, renders the code in a read-only console.

    Or, if it can generate a new link "tag", of which it's read only? Not sure how it's implemented internally but either way, I would love this option if considered. Thanks.

    opened by binarydad 3
  • Bug/Discussion: Cursor-Position in collaborative coding

    Bug/Discussion: Cursor-Position in collaborative coding

    When using this I've stumbled upon an issue. I'm not sure if my suggested fix is actually always a good idea, or how easy it would be to solve, so this should probably be discussed.

    If multiple persons work in different areas of a file, this can lead to conflicts, when the person that is closer to the beginning of the file inserts/deletes newlines, or with both in a single line just when it enters anything.

    Because this will not change the position of the cursor of the other person in the file, meaning its cursor will move in relation to the context the person was working on, since that context is indirectly moved by the other person.

    This can be fairly disrupting, if one was currently writing something, it might be spread over multiple lines or be... interlaced with the past characters.

    The fix would be to move the cursor accordingly, depending on its current position. If its on the same line and past the other cursor, it has to be moved forward, if its simply below, it has to be moved down, if its above or generally before the other cursor, it doesn't get influenced.

    opened by 9SMTM6 3
  • Add multi-platform build support for linux/arm64

    Add multi-platform build support for linux/arm64

    Changes

    • Add multi-platform build to the CI pipeline, currently specifying linux/amd64,linux/arm64 QEMU targets.
    • Specify amd64/ prefixes for the frontend build stages to avoid wasm-pack compatibility failures.

    This fixes #31. It should allow ARM users to pull the image from Docker Hub.

    The only downside is that this will probably make the CI / build step about twice as slow, but that seems like a reasonable tradeoff to me. Thanks GitHub for sponsoring free Actions time for public repositories. :)

    opened by ekzhang 3
  • Enable state persistence through SQLite

    Enable state persistence through SQLite

    Summary

    We add a new environment variable, SQLITE_URI, to Rustpad. When this is set to a connection string (e.g., sqlite://rustpad.db), Rustpad's behavior will change to automatically persist documents to the database, every 3 seconds, if there has been a change. These documents will remain between server restarts and after documents are automatically cleaned from in-memory data structures due to inactivity, which provides some form of file system-based persistence.

    This resolves #6.

    opened by ekzhang 3
Owner
Eric Zhang
Student at Harvard University and competitive programmer, with research in machine learning & programming languages. @scaleapi, @NVIDIA, @HarvardPL
Eric Zhang
Dip editor: Multi-platform Text editor purely written in Rust

dip editor Multi-platform Text editor purely written in Rust, supercharged by Bevy game engine and Dioxus UI framework. heavily in development Why Gam

Junichi Sugiura 162 Sep 24, 2022
Lightning-fast and Powerful Code Editor written in Rust

Lapce Lightning-fast and Powerful Code Editor written in Rust About Lapce is written in pure Rust, with UI in Druid. It's using Xi-Editor's Rope Scien

Lapce 18k Sep 26, 2022
A text editor in ≤1024 lines of code, written in Rust

Kibi: A text editor in ≤1024 lines of code, written in Rust A configurable text editor with UTF-8 support, incremental search, syntax highlighting, li

Ilaï Deutel 839 Sep 24, 2022
An opinionated modal editor to simplify code editing from the terminal

(I'm currently refactoring the platform layer. So we have to first finish this cleanup before we're able to continue adding features) An opinionated m

Matheus Lessa Rodrigues 271 Sep 24, 2022
A package manager for the Lite-XL code editor

Lite-XL Package Manager (lpm) (Under Development) lpm is an attempt to create a package manager for the Lite-XL code editor. It's primary goal is to p

Debarchito Nath 9 Aug 29, 2022
My own personal code editor built with Rust + OpenGL

Glyph This is my personal code editor that I am building for fun and to get more familiar with OpenGL. Glyph currently supports Vim keybinds, syntax h

Zack Radisic 71 Sep 14, 2022
Borderlands 3 Save/Profile Editor for Windows/MacOS and Linux!

Borderlands 3 Save Editor A tool to help you modify your Borderlands 3 Saves and Profiles. Currently it runs on Windows, Mac OS and Linux. It supports

Zak 178 Sep 19, 2022
A pathtracer written in rust - runs in the web and includes an editor

Webtracer A pathtracer written in rust - runs in the web and includes an editor Rendering is parallelized and utilizes all cpu cores You can easily ed

Shapur 2 Aug 29, 2022
A terminal-based text editor written in Rust

Iota Iota is a terminal-based text-editor written in Rust. Here's what it looks like right now, editing itself. Motivation Iota was born out of my fru

Greg Chapple 1.5k Sep 20, 2022
Aspiring vim-like text editor

Rim Rim is an aspiring Vim-like text editor written in Rust. Current state Rim is in an early prototype stage. This means that you can load, edit and

Mathias Hällman 547 Sep 24, 2022
An independent Rust text editor that runs in your terminal!

Ox editor Ox is a code editor that runs in your terminal. About The Project Ox is a code editor. It was written in Rust using ANSI escape sequences. I

null 2.8k Sep 16, 2022
A modern editor with a backend written in Rust.

Xi Editor (pronounced "Zigh") A modern editor with a backend written in Rust. Maintenance status: The xi-editor project is not currently under active

null 19.6k Sep 27, 2022
An experimental next-generation Electron-based text editor

Attention: GitHub has decided not to move forward with any aspect of this project. We'll archive the repository in case anybody finds value here, but

Atom Archive 8.6k Sep 22, 2022
Web base text editor written in rust

Ultron Ultron is a web based monospace text-editor with syntax highlighting, completely written in rust. I wrote this code editor for my very specific

Jovansonlee Cesar 59 Aug 8, 2022
A save editor for Mass Effect Trilogy

Trilogy Save Editor A save editor for Mass Effect Trilogy A bit late but just in time ! This software is similar to Gibbed's save editors (and forks)

Karlitos 109 Sep 13, 2022
ReVi is a cross-platform terminal based Vim inspired text editor.

ReVi Table Of Contents: About Usage Install Clone && Installing Development Q&A KeyBindings Roadmap Changelog About ReVi is a cross-platform terminal

null 30 Aug 25, 2022
Rust-based traffic editor for RMF

Traffic Editor III Welcome to Traffic Editor III. install stuff Unfortunately we need a newer Rust than what comes with Ubuntu 20.04. First make sure

null 1 Nov 26, 2021
A simple terminal-based editor made in rust!

ELuna Editor The terminal-based editor for europa lang. Goals Be as minimal as possible, but retain conveniences found in other editors. Do not add fe

Junhao 3 May 25, 2022
Ginkgo is a text editor built entirely in Rust

Ginkgo is a text editor built entirely in Rust. It supports cursor movements, CTRL commands, select vim commands, insert vs. normal modes, and more. Ginkgo is based on my text editor JED, which itself was based on the popular online editor Kilo.

James Asbury 11 Mar 21, 2022