👨‍💻👩‍💻 Write Markdown. Together.

Overview

👨‍💻 👩‍💻 LetsMarkdown.com

Fast, minimal web editor that makes markdown editing collaborative and accessible to everyone.


LetsMarkdown.com

Motivation

> I want to edit markdown files with my friends, but sending/resending files, changing viewing access, version control, and previewing are just too much work.

> 💡 why not create a google doc for collaborative markdown editing, without having to log into Google, change view/edit access, worry about previewing the file, etc?

> Voilà, after hours of laborious coding, LetsMarkdown.com is born!

Features

  • Live collaborative markdown editing and preview
  • VSCode-like editor with support for command palette (syntax highlighting, autocomplete, editor themes...)
  • Minimal setup with no login required - say goodbye to malicious trackers and privacy invasions
  • Efficient backend built with Rust and WebAssembly
  • Dark mode (duh)
  • Emoji support with shortcuts enabled
  • (Upcoming) cursors tracking, synced scrolling, subscript/footnote/insert support, and more

Tech Stack

  • Frontend: React.js (TypeSript), Vite.js, Chakra UI
    • Editor & markdown preview: Monaco, mardown-it.js, highlight.js
  • Backend: Rust, WebAssembly, Node.js
  • Deployment & hosting: Docker, DigitalOcean
  • CI/CD: Github Action
  • Formatting: Prettier, Rustfmt
  • Design & prototyping: Figma

Development Info

This application is built using a backend operational transformation control server written in Rust (based on Rustpad), and a frontend written in TypeScript using React.js.

The backend server supports real-time collaborative editing sessions, and the frontend offers a collaborative text editor with built-in markdown syntax highlighting and auto-completion. These parts of the application are connected via WebSocket communication.

For markdown previewing, I used the markdown-it.js library to dynamically render the markdown file. To style the markdown file, I also created a custom markdown.css stylesheet.

To develop this application locally, you need to:

First, install Rust, wasm-pack, and Node.js. Verify your installation with:

rustup -V && wasm-pack -V && npm -v

Then, build the WebAssembly part of the app:

wasm-pack build --target web letsmarkdown-wasm

After that, install the dependencies for the React application:

npm install

Next, you can 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 dev server.

npm run dev

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

Deployment

LetsMarkdown.com 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. It has multi-platform support for linux/amd64 and linux/arm64.

docker pull cveinnt/letsmarkdown

(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 cveinnt/letsmarkdown

I deploy a public instance of this image with DigitalOcean App Platform.

Contributing

This project is still in a very early phase. If you're interested in adding new features or fixing bugs, please reach out to me by creating a GitHub issue!

I plan to integrate this repository continuously, and the code base already accounts for things like code style (Prettier, Rustfmt) and build success (Docker). The current state of the main branch is continuously deployed to the production web server at LetsMarkdown.com.

Credits

LetsMarkdown.com is inspired by composing.studio, which is based on Rustpad.


All code is licensed under the MIT license.
Comments
  • Multi-arch does not seem to be supported

    Multi-arch does not seem to be supported

    Hello!

    The README mentions that the Docker image supports multi-arch, but that does not appear to be the case here?

    https://hub.docker.com/r/cveinnt/letsmarkdown/tags

    opened by agneevX 4
  • Font size of code, in headings, and border box.

    Font size of code, in headings, and border box.

    See https://letsmarkdown.com/spurious-kick-1370

    The code tags should follow the font-height for the heading element they are contained in, but they are all exactly font-height: 12px;. I think changing this to a relative value, like font-height: 0.9em; could be sufficient to solve this issue in https://github.com/Cveinnt/LetsMarkdown.com/blob/d53114d36ac265989301c12a52f8a5e72dc25e30/src/components/markdown.css#L109

    Moreover, if you browse <insert random MDN docs> as reference, you will see that they are using a font that has an Ascender (space above Capsize, i.e. font height) that balances out with the Descender (space below baseline, i.e. below font).[^1] This leads to the box around the text being more "center" than currently, where there appears to be less space above the font than below it. I'm sure you could find a suitable font for this.

    Screenshot of the wrong font-height and missing Ascender, on current Firefox

    screenshot

    [^1]: Terminology from https://seek-oss.github.io/capsize/

    opened by WorldSEnder 2
  • Implement XSS prevention measures

    Implement XSS prevention measures

    Please consider adding XSS countermeasures for this product. It's possible to run an arbitrary JavaScript code.

    To reproduce

    1. go to https://letsmarkdown.com/
    2. Get the generated URL ( https://letsmarkdown.com/pink-things-6832 )
    3. Add the following details
    <img src=1 onerror="console.log(top.document.body.innerHTML='Unexpected_Page')">
    
    1. Ask people to access https://letsmarkdown.com/pink-things-6832

    Suggested Fix

    Consider disabling HTML feature on src/components/Score.tsx, or use the sanitizer package while HTML is turned on.

    https://github.com/Cveinnt/LetsMarkdown.com/blob/d88c75b132e60733a5bc3eae43cf72d82eaafa4d/src/components/Score.tsx#L30

    I assume HTML tags are not required for the most of the time.

    Reference: https://github.com/markdown-it/markdown-it/blob/master/docs/security.md

    opened by stypr 1
  • Websockets support needs to be enabled if hosted behind a reverse proxy

    Websockets support needs to be enabled if hosted behind a reverse proxy

    Hello,

    Thanks for making this, it's very useful! I was hosting the editor behind a Nginx reverse proxy using the Nginx Proxy Manager which I believe is pretty common amongst self-hosting enthusiasts and found out that the "Websockets Support" option was required to be enabled if not you would not be able to connect to the server to save your notes for collaboration. Just mentioning it here in case someone else faces the same problem.

    opened by MarseyLivesMatter 1
  • A Few Questions

    A Few Questions

    I'm not sure if I am just a newbie, or if there are a few features missing (I understand it's under development and it's early)

    My main question is that, I deployed on docker using the instructions, how do I change the volumes so I can change the path at the top? (Seems to default to documents>randomlygeneratedname) Or is this by design? Do I have to install on bare metal to be able to save these files to the system? Not quite sure how it all works.

    Assuming there is nothing saved in a database or on the system, and its just a editor to view and collaborate in the browser, then I think an ability to upload a markdown file to continue editing (although you can copy and paste, so this may not be needed) as well as a way to export the document (again, can copy and paste, but a button to import/export would be nice).

    Overall, I really like the UI and it's simplicity. Looking forward to this projects future.

    opened by LordZeuss 0
  • Docker persistent storage

    Docker persistent storage

    I guess when using https://<url>/<file-name> we create a new file to be edited. I do want the files to be stored persistently. How can I achieve this in docker? I can't even use docker exec -it <container-name> sh (or any other shell) to explore the directory structure. tl;dr: what folder to mount using docker, to have possible persistent storage? (maybe include it in the README.md)

    opened by SoulEater45 1
Owner
Vincent Wu
I like ml, art, and philosophy.
Vincent Wu
Reference for How to Write an Open Source JavaScript Library - https://egghead.io/series/how-to-write-an-open-source-javascript-library

Reference for How to Write an Open Source JavaScript Library The purpose of this document is to serve as a reference for: How to Write an Open Source

Sarbbottam Bandyopadhyay 175 Dec 24, 2022
Learn GraphQL by building a blogging engine. Create resolvers, write schemas, write queries, design the database, test and also deploy.

GraphQL Blog graphqlblog.com Learn GraphQL by building a blogging engine. Create resolvers, write schemas, write queries, design the database, test an

GraphQLApps 6 Aug 17, 2022
Chappe - 🧑‍💻 Developer Docs builder. Write guides in Markdown and references in API Blueprint. Comes with a built-in search engine.

Chappe Developer Docs builder. Write guides in Markdown and references in API Blueprint. Comes with a built-in search engine. Chappe is a Developer Do

Valerian Saliou 146 Jan 1, 2023
🧑‍💻 Developer Docs builder. Write guides in Markdown and references in API Blueprint. Comes with a built-in search engine.

Developer Docs builder. Write guides in Markdown and references in API Blueprint. Comes with a built-in search engine. Chappe is a Developer Docs buil

Crisp (OSS) 146 Jan 1, 2023
📝 [WIP] Write your reports in markdown, and get them in docx.

md-report What's md-report The repo name md-report stands for both "Write your reports in markdown, and get them in docx." and "Made report again." ("

Yiyang Sun 8 Jun 12, 2022
MySQL meets Jupyter notebooks. Grasp provides a new way to learn and write SQL, by providing a coding-notebook style with runnable blocks, markdown documentation, and shareable notebooks. ✨

A New Way to Write & Learn SQL Report Bug · Request Feature Table of Contents About The Project Built With Getting Started Prerequisites Installation

Lakshya 7 Sep 1, 2022
A plugin for the Obsidian markdown note application, adding functionality to render markdown documents with multiple columns of text.

Multi-Column Markdown Take your boring markdown document and add some columns to it! With Multi Column Markdown rather than limiting your document lay

Cameron Robinson 91 Jan 2, 2023
A markdown-it plugin that process images through the eleventy-img plugin. Can be used in any projects that uses markdown-it.

markdown-it-eleventy-img A markdown-it plugin that process images through the eleventy-img plugin. Can be used in any projects that use markdown-it. F

null 25 Dec 20, 2022
An obsidian plugin for uploading local images embedded in markdown to remote store and export markdown for publishing to static site.

Obsidian Publish This plugin cloud upload all local images embedded in markdown to specified remote image store (support imgur only, currently) and ex

Addo.Zhang 7 Dec 13, 2022
Markdown Transformer. Transform markdown files to different formats

Mdtx Inspired by generative programming and weed :). So I was learning Elm language at home usually in the evening and now I am missing all this gener

Aexol 13 Jan 2, 2023
BIND-ing the good features together.

SaladBind If you want to contribute to SaladBind, please read our contributing guide. Table of Contents Features Installation Configuration Miner Setu

Vukky Limited 7 May 31, 2022
LearnR is an educators application that aims to bring together students and teachers on the community platform.

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

Emerenini Cynthia Ngozi 0 Sep 5, 2022
It consists of a recreation of Twitter, to put into practice both Front-end and Back-end knowledge by implementing the MERN Stack together with other technologies to add more value to the project.

Twitter-Clone_Back-end ✨ Demo. ?? About the project. ?? Descriptions. It consists of a recreation of Twitter, to put into practice knowledge of both F

Mario Quirós Luna 5 Apr 12, 2022
@nodesecure/ci brings together a set of tools to identify dependencies vulnerabilities and track most common malicious code and patterns

NodeSecure CI Action @nodesecure/ci brings together a set of tools to identify dependencies vulnerabilities and track most common malicious code and p

null 7 Jul 29, 2022
ICT (Ideas Come Together) - SPA Team Project

ICT (Ideas Come Together) - SPA Team Project This is a team project for our ReactJS module in our webdev program.

Ashley 3 Jul 3, 2022
Clubhouse is a new type of social network based on voice—where people around the world come together to talk, listen and learn from each other in real-time.

Awesome Clubhouse The clubhouse is a new type of social network based on voice—where people around the world come together to talk, listen and learn f

Ehsan Ghaffar 27 Nov 9, 2022
Full source-code for the step-by-step tutorial on how to use Phaser + Colyseus together.

Phaser: Real-time Multiplayer with Colyseus Full source-code for the step-by-step tutorial on how to use Phaser + Colyseus together. Live Demo See ste

Colyseus 19 Dec 24, 2022
We are students of group named "Special-Team" of GоIT academy. We graduated JavaScript course and for consolidate in practice 📌 knowledges received on this course, we together 🤝 developed graduation project

Проект сайту "Filmoteka" Привіт! ?? Ми студенти групи під назвою "Special-Team" академії GоIT ?? ?? Ми закінчили курс JavaScript і для того, щоб закрі

Oksana Banshchykova 12 Jan 3, 2023
An Advanced Activity Command Using Discord-Together Package For Discord.jsv13 with buttons

Active An Advanced Activity Bot Using Discord-Together Package For Discord.jsv13 with buttons. Report Bug · Request Feature Usage. How to run the bot?

Hypwreck 11 Feb 15, 2022