{"id":17274008,"url":"https://github.com/owulveryck/gomarkablestream","last_synced_at":"2026-02-15T12:04:35.751Z","repository":{"id":38886477,"uuid":"323294781","full_name":"owulveryck/goMarkableStream","owner":"owulveryck","description":"A utility to stream (and record) from a Remarkable2 without hack or third party dependencies","archived":false,"fork":false,"pushed_at":"2025-03-03T14:29:46.000Z","size":26994,"stargazers_count":643,"open_issues_count":27,"forks_count":26,"subscribers_count":10,"default_branch":"main","last_synced_at":"2025-03-29T01:08:07.567Z","etag":null,"topics":["golang","hacktoberfest","remarkable-tablet"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/owulveryck.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["owulveryck"],"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":null}},"created_at":"2020-12-21T09:54:37.000Z","updated_at":"2025-03-28T07:20:15.000Z","dependencies_parsed_at":"2022-09-01T12:21:09.916Z","dependency_job_id":"3eab8632-04ef-4ad8-ae77-ce71d1a9dfd5","html_url":"https://github.com/owulveryck/goMarkableStream","commit_stats":{"total_commits":350,"total_committers":8,"mean_commits":43.75,"dds":0.0714285714285714,"last_synced_commit":"087878dfbd8d7f432c6010f5d260f99fae2fa916"},"previous_names":[],"tags_count":42,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/owulveryck%2FgoMarkableStream","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/owulveryck%2FgoMarkableStream/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/owulveryck%2FgoMarkableStream/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/owulveryck%2FgoMarkableStream/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/owulveryck","download_url":"https://codeload.github.com/owulveryck/goMarkableStream/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247276164,"owners_count":20912288,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["golang","hacktoberfest","remarkable-tablet"],"created_at":"2024-10-15T08:52:52.035Z","updated_at":"2026-02-10T17:11:23.835Z","avatar_url":"https://github.com/owulveryck.png","language":"Go","funding_links":["https://github.com/sponsors/owulveryck"],"categories":[],"sub_categories":[],"readme":"[![Go](https://github.com/owulveryck/goMarkableStream/actions/workflows/go.yml/badge.svg)](https://github.com/owulveryck/goMarkableStream/actions/workflows/go.yml)\n![Static Badge](https://img.shields.io/badge/reMarkable_2-Firmware_3.24+-green)\n\n# goMarkableStream\n\n[Screen recording 2026-02-04 11.24.44.webm](https://github.com/user-attachments/assets/facdf1c5-41b2-4b82-bb84-2dd169858a80)\n\n\n\n## Overview\n\ngoMarkableStream is a lightweight and user-friendly application designed specifically for the reMarkable tablet.\n\nIts primary goal is to enable users to stream their reMarkable tablet screen to a web browser without the need for any hacks or modifications that could void the warranty.\n\n## Table of Contents\n- [Device Support](#device-support)\n- [Available Binaries](#available-binaries)\n- [Quick Start](#quick-start)\n- [Systemd Service Setup](#setup-as-a-systemd-service)\n- [Subcommands](#subcommands)\n- [Configuration](#configurations)\n- [Presentation Mode](#presentation-mode)\n- [Technical Details](#technical-details)\n- [Compilation](#compilation)\n- [Contributing](#contributing)\n\n## Device Support\n\n**Actively supported and tested:**\n- reMarkable 2 with firmware 3.24+\n\n**Experimental (not actively tested):**\n- reMarkable Paper Pro - initial support, some features may not work as expected\n\n## Version Support\n\nThe latest version of goMarkableStream is actively developed and tested on reMarkable 2 with firmware 3.24+.\n\nFor older firmware versions:\n- Firmware \u003c 3.4: use goMarkableStream version \u003c 0.8.6\n- Firmware \u003e= 3.4 and \u003c 3.6: use version \u003e= 0.8.6 and \u003c 0.11.0\n- Firmware \u003e= 3.6 and \u003c 3.24: use version \u003e= 0.11.0 (may work, but not actively tested)\n\n## Features\n\n### Core Benefits\n- **No Warranty Voiding**: Operates within the reMarkable tablet's intended functionality without unauthorized modifications.\n- **No Subscription Required**: Completely free to use, with no subscription fees.\n- **No Client-Side Installation**: Access directly through a web browser, no additional software needed.\n- **HTTPS by Default**: Secure encrypted connections out of the box.\n\n### Streaming\n- **Full Color Support**: RGBA streaming with full color from PDFs and documents (firmware 3.24+).\n- **High Performance**: WebGL-based rendering for smooth, efficient display.\n- **Delta Compression**: Bandwidth-efficient streaming that only transmits changed pixels.\n- **Configurable Frame Rate**: Adjust streaming rate via URL parameters.\n\n### Remote Access (Tailscale)\n- **Tailscale Integration**: Access your reMarkable from anywhere on your tailnet without exposing it to the public internet.\n- **Tailscale Funnel**: Share your screen publicly via Tailscale Funnel with automatic QR code generation.\n- **Ephemeral Mode**: Register as a temporary node that's automatically removed when disconnected.\n\n### Interaction\n- **Laser Pointer**: Red laser pointer that follows pen hover position (toggle with `L` key).\n- **Gesture Support**: Swipe gestures for slide navigation, integrated with Reveal.js presentations.\n- **Keyboard Shortcuts**: `R` for rotation, `L` for laser pointer, `?` for help overlay.\n- **Layer Control**: Toggle drawing layer above or below embedded content.\n\n### Presentation Mode\n- **Overlay Feature**: Embed presentations or videos in the background for live annotation.\n- **Reveal.js Integration**: Full slide control directly from your reMarkable tablet.\n\n### UI\n- **Side Menu**: Collapsible sidebar for rotation, layer control, and Funnel toggle.\n- **Connection Status**: Visual indicator showing connection state with auto-reconnection.\n- **Help Overlay**: Press `?` to view all available gestures and shortcuts.\n\n## Available Binaries\n\nEach release provides four binary variants:\n\n| Binary | Device | Tailscale Support |\n|--------|--------|-------------------|\n| `gomarkablestream-RMPRO` | reMarkable Paper Pro (arm64) | Yes |\n| `gomarkablestream-RM2` | reMarkable 2 (arm) | Yes |\n| `gomarkablestream-RMPRO-lite` | reMarkable Paper Pro (arm64) | No |\n| `gomarkablestream-RM2-lite` | reMarkable 2 (arm) | No |\n\n**Which binary should I use?**\n- Use `RMPRO` variants for reMarkable Paper Pro\n- Use `RM2` variants for reMarkable 2\n- Use `-lite` variants if you don't need Tailscale remote access (smaller binary size)\n\n## Quick Start\n\n1. Connect your reMarkable to your computer via USB-C cable and SSH into it:\n```bash\nssh root@10.11.99.1\n```\n\n2. Download and run (choose your device):\n```bash\n# Set your device: RM2 for reMarkable 2, RMPRO for Paper Pro\nDEVICE=RM2\n\n# Download latest version\nVERSION=$(wget -q -O - https://api.github.com/repos/owulveryck/goMarkableStream/releases/latest | grep tag_name | awk -F\\\" '{print $4}')\nwget -O goMarkableStream https://github.com/owulveryck/goMarkableStream/releases/download/$VERSION/gomarkablestream-$DEVICE\nchmod +x goMarkableStream\n./goMarkableStream\n```\n\n3. Open https://10.11.99.1:2001 in your browser\n   - Default credentials: `admin` / `password`\n\n_Note_: You can also connect via Wi-Fi using your tablet's IP address or `remarkable.local.` (with trailing dot) on Apple devices.\n\nFor lite versions (without Tailscale), append `-lite` to the device name: `gomarkablestream-RM2-lite`\n\nTo update to a new version, use the built-in download command: `./goMarkableStream download` (see [Subcommands](#subcommands)).\n\n### Errors due to missing packages\n\nIf you get errors such as `wget: note: TLS certificate validation not implemented`, download goMarkableStream on your local computer and copy it over:\n\n```bash\n# On your local computer (set DEVICE to RM2 or RMPRO)\nDEVICE=RM2\nVERSION=$(wget -q -O - https://api.github.com/repos/owulveryck/goMarkableStream/releases/latest | grep tag_name | awk -F\\\" '{print $4}')\nwget -O goMarkableStream https://github.com/owulveryck/goMarkableStream/releases/download/$VERSION/gomarkablestream-$DEVICE\nchmod +x goMarkableStream\n\n# Copy to reMarkable (via USB-C)\nscp ./goMarkableStream root@10.11.99.1:/home/root/goMarkableStream\n\n# SSH and run\nssh root@10.11.99.1 ./goMarkableStream\n```\n\n## Setup as a Systemd Service\n\nThe easiest way to install goMarkableStream as a systemd service is using the built-in `install` subcommand:\n\n```bash\n./goMarkableStream install\n```\n\nThis will create the service file and enable it to start automatically on boot. You can change the settings by editing `/home/root/.config/goMarkableStream/env`\n\nAlternatively, you can manually create the service file after connecting via USB-C (`ssh root@10.11.99.1`):\n\n```bash\ncat \u003c\u003c'EOF' \u003e /etc/systemd/system/goMarkableStream.service\n[Unit]\nDescription=goMarkableStream Server\n\n[Service]\nExecStart=/home/root/goMarkableStream\nRestart=always\n\n[Install]\nWantedBy=multi-user.target\nEOF\n\nsystemctl daemon-reload\nsystemctl enable --now goMarkableStream.service\n```\n\nTo check status: `systemctl status goMarkableStream.service`\n\nTo view logs: `journalctl -u goMarkableStream.service`\n\nTo stop: `systemctl stop goMarkableStream.service`\n\n**Note:** After a reMarkable system update, you may need to re-download the binary and restart the service.\n\n## Subcommands\n\ngoMarkableStream provides built-in subcommands to simplify installation and updates:\n\n### install\n\nInstalls goMarkableStream as a systemd service for automatic startup:\n\n```bash\n./goMarkableStream install\n```\n\nThis command:\n- Creates the systemd service file at `/etc/systemd/system/goMarkableStream.service`\n- Reloads the systemd daemon\n- Enables and starts the service\n\n### download\n\nDownloads the latest version from GitHub releases:\n\n```bash\n./goMarkableStream download\n```\n\nThis command:\n1. Computes the SHA256 checksum of the currently running binary\n2. Fetches the latest release from GitHub\n3. Compares the current checksum against all binaries in the release\n4. If you're already running the latest version, it tells you\n5. If a newer version is available, prompts you to confirm the download\n6. Lists all available binaries and lets you choose which one to download\n7. Downloads and verifies the checksum of the selected binary\n8. Asks if you want to replace the current binary with the downloaded one\n\nThis is the recommended way to update goMarkableStream on your device.\n\n## Configurations\n\n### Device Configuration\nConfigure the application via environment variables:\n- `RK_SERVER_BIND_ADDR`: (String, default: `:2001`) Server bind address.\n- `RK_SERVER_USERNAME`: (String, default: `admin`) Username for server access.\n- `RK_SERVER_PASSWORD`: (String, default: `password`) Password for server access.\n- `RK_HTTPS`: (True/False, default: `true`) Enable or disable HTTPS.\n- `RK_DEV_MODE`: (True/False, default: `false`) Enable or disable developer mode.\n- `RK_DELTA_THRESHOLD`: (Float, default: `0.30`) Change ratio threshold (0.0-1.0) above which a full frame is sent instead of delta.\n\n### Tailscale Configuration\n\nTailscale allows secure remote access to your reMarkable tablet from anywhere on your tailnet, without exposing the device to the public internet. When enabled, goMarkableStream creates both a local listener (on `RK_SERVER_BIND_ADDR`) and a Tailscale listener.\n\n**Requirements:**\n- Build with the `tailscale` tag: `go build -tags tailscale`\n- A Tailscale account\n\n**Environment variables:**\n- `RK_TAILSCALE_ENABLED`: (True/False, default: `false`) Enable Tailscale listener.\n- `RK_TAILSCALE_PORT`: (String, default: `:8443`) Tailscale listener port.\n- `RK_TAILSCALE_HOSTNAME`: (String, default: `gomarkablestream`) Device name in your tailnet.\n- `RK_TAILSCALE_STATE_DIR`: (String, default: `/home/root/.tailscale/gomarkablestream`) State directory for Tailscale.\n- `RK_TAILSCALE_AUTHKEY`: (String, default: empty) Auth key for headless setup. If unset, Tailscale will display a login URL in the console for interactive authentication.\n- `RK_TAILSCALE_EPHEMERAL`: (True/False, default: `false`) Register as ephemeral node (removed when disconnected). **Recommended for most users.** When enabled, a random suffix is appended to the hostname (e.g., `gomarkablestream-a1b2c3`) to avoid naming conflicts if multiple instances are started.\n- `RK_TAILSCALE_FUNNEL`: (True/False, default: `false`) Enable public internet access via Tailscale Funnel.\n- `RK_TAILSCALE_USE_TLS`: (True/False, default: `false`) Use Tailscale's automatic TLS certificates.\n- `RK_TAILSCALE_VERBOSE`: (True/False, default: `false`) Verbose Tailscale logging.\n\n**Example usage:**\n\n```bash\n# Enable Tailscale with interactive login (displays login URL in console)\nRK_TAILSCALE_ENABLED=true ./goMarkableStream\n\n# Enable Tailscale with auth key (headless setup)\nRK_TAILSCALE_ENABLED=true RK_TAILSCALE_AUTHKEY=tskey-auth-xxx ./goMarkableStream\n\n# Recommended: ephemeral mode with auth key (node removed on disconnect, random hostname suffix)\nRK_TAILSCALE_ENABLED=true RK_TAILSCALE_EPHEMERAL=true RK_TAILSCALE_AUTHKEY=tskey-auth-xxx ./goMarkableStream\n\n# Access via Tailscale: https://gomarkablestream.your-tailnet.ts.net:8443\n# Access locally: https://remarkable.local.:2001\n```\n\n**Systemd service with Tailscale:**\n\nAdd the environment variables to your systemd service file:\n```bash\n[Service]\nEnvironment=\"RK_TAILSCALE_ENABLED=true\"\nEnvironment=\"RK_TAILSCALE_AUTHKEY=tskey-auth-xxx\"\nExecStart=/home/root/goMarkableStream\n```\n\n### Endpoint Configuration\nAdd query parameters to the URL (`?parameter=value\u0026otherparameter=value`):\n- `color`: (true/false) Enable or disable color.\n- `portrait`: (true/false) Enable or disable portrait mode.\n- `rate`: (integer, 100-...) Set the frame rate.\n- `flip`: (true/false) Enable or disable flipping 180 degrees.\n\n### API Endpoints\n- `/`: Main web interface\n- `/stream`: The image data stream\n- `/events`: WebSocket endpoint for pen input events\n- `/gestures`: Endpoint for touch events\n- `/version`: Returns the current version of goMarkableStream\n\n## Presentation Mode\n`goMarkableStream` introduces an innovative experimental feature that allows users to set a presentation or video in the background, enabling live annotations using a reMarkable tablet.\nThis feature is ideal for enhancing presentations or educational content by allowing dynamic, real-time interaction.\n\n### How It Works\n\n- To use this feature, append `?present=https://url-of-the-embedded-file` to your streaming URL.\n- This action will embed your chosen presentation or video in the stream's background.\n- You can then annotate or draw on the reMarkable tablet, with your input appearing over the embedded content in the stream.\n\n### Usage Example\n\n- **Live Presentation Enhancement**: For instance, using Google Slides, you can leave spaces in your slides or use a blank slide to write additional content live.\nThis feature is perfect for educators, presenters, and anyone looking to make their presentations more interactive and engaging.\n\n![](docs/gorgoniaExample.png)\n\n### Compatibility\n\n- The feature works with any content that can be embedded in an iframe.\nThis includes a variety of presentation and video platforms.\n- Ensure that the content you wish to embed allows iframe integration.\n\n`goMarkableStream` is fully integrated with Reveal.js, making it a perfect tool for presentations.\nSwitch slides or navigate through your presentation directly from your reMarkable tablet.\nThis seamless integration enhances the experience of both presenting and viewing, making it ideal for educational and professional environments.\n\nHow to: add the `?present=https://your-reveal-js-presentation`\n\n_Note_: Due to browser restrictions, the URL must be HTTPS.\n\n### Limitations and Performance\n\n- **Screen Size**: Currently, the drawing screen size on the tablet is smaller than the presentations, which may affect how content is displayed.\n- **Control**: There is no way to control the underlying presentation directly from the tablet.\nUsers must use the side menu for navigation and control.\n- This feature operates seamlessly, with no additional load on the reMarkable tablet, as all rendering is done in the client's browser.\n\n## Technical Details\n\nThis tool suits my needs and is an ongoing development. You can find various information about the journey on my blog:\n- [Streaming the reMarkable 2](https://blog.owulveryck.info/2021/03/30/streaming-the-remarkable-2.html)\n- [Evolving the Game: A clientless streaming tool for reMarkable 2](https://blog.owulveryck.info/2023/07/25/evolving-the-game-a-clientless-streaming-tool-for-remarkable-2.html)\n\n### reMarkable HTTP Server\n\nThis is a standalone application that runs directly on a reMarkable tablet.\nIt does not have any dependencies on third-party libraries, making it a completely self-sufficient solution.\nThis application exposes an HTTP server with several endpoints.\n\n### Implementation\n\nThe image data is read directly from the main process's memory as a BGRA byte array.\n\n**Delta Compression**: The streaming uses delta encoding to minimize bandwidth:\n- Only changed pixels are sent between frames (typically 1-5% for e-ink usage)\n- Full frames are gzip-compressed (~5-10x reduction) and sent when \u003e30% of pixels change or on first connection\n- Delta frames encode runs of changed pixels with their positions\n\nThe CPU footprint is relatively low, using about 10% of the CPU for a frame every 200 ms.\nYou can increase the frame rate, but it will consume slightly more CPU.\n\nOn the client side, the streamed byte data is decoded (with automatic gzip decompression for full frames using the browser's native DecompressionStream API) and displayed on a canvas through WebGL.\n\nAdditionally, the application features a side menu which allows users to rotate the displayed image.\nAll image transformations utilize native browser implementations, providing optimized performance.\n\n## Compilation\n\n```bash\nGOOS=linux GOARCH=arm GOARM=7 CGO_ENABLED=0 go build -v -trimpath -ldflags=\"-s -w\" .\n```\n\nTo install and run, you can then execute:\n\n```bash\nscp goMarkableStream root@remarkable:\nssh root@remarkable ./goMarkableStream\n```\n\n## Contributing\n\nI welcome contributions from the community to improve and enhance the reMarkable Screen Streaming Tool.\nIf you have any ideas, bug reports, or feature requests, please submit them through the GitHub repository's issue tracker.\n\n## License\n\nThe reMarkable Screen Streaming Tool is released under the [MIT License](https://opensource.org/licenses/MIT) .\nFeel free to modify, distribute, and use the tool in accordance with the terms of the license.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fowulveryck%2Fgomarkablestream","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fowulveryck%2Fgomarkablestream","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fowulveryck%2Fgomarkablestream/lists"}