Skip to content

e01n0/termarkable

termarkable

A native terminal emulator with SSH for the reMarkable Paper Pro.

Renders directly to the e-ink framebuffer, supports the Type Folio keyboard and touchscreen gestures, and connects to remote hosts over SSH.

Status: Early-stage, actively developed. Contributions welcome!

Features

  • Full terminal emulation — VT100/ANSI via alacritty_terminal
  • Local shell — PTY-backed shell sessions directly on the device
  • SSH client — Password and key authentication via russh
  • E-ink optimized rendering — Direct framebuffer access with partial refresh and DU/GC16 waveforms
  • Type Folio keyboard — Full evdev keyboard input
  • Touch gestures — Swipe to scroll terminal history
  • Connection menu — Interactive UI to pick shell or SSH targets
  • Status bar — Session info at a glance
  • AppLoad integration — Launch from the reMarkable home screen

Requirements

  • reMarkable Paper Pro with Developer Mode enabled
  • cross and Docker (for cross-compilation)
  • Rust toolchain (stable)

Building

cargo install cross --git https://github.com/cross-rs/cross
cross build --release --target aarch64-unknown-linux-gnu

The binary will be at target/aarch64-unknown-linux-gnu/release/termarkable.

Deploying

Enable Developer Mode on your reMarkable Paper Pro: Settings → General → Paper Tablet → Software → Advanced → Developer Mode

The device exposes a USB network interface at 10.11.99.1 by default.

# Automated deploy (builds, bundles AppLoad app, and copies over USB):
./deploy.sh

# Or manually:
scp target/aarch64-unknown-linux-gnu/release/termarkable root@10.11.99.1:/home/root/
ssh root@10.11.99.1
systemctl stop xochitl
./termarkable
systemctl start xochitl

AppLoad deployment

deploy.sh packages termarkable as an AppLoad application so it appears in the device's app launcher. It builds the binary, generates the QML resource bundle, and copies everything to the AppLoad directory on the device.

Usage

# Interactive menu (default)
./termarkable

# Direct local shell
./termarkable shell

# Direct SSH connection
./termarkable ssh user@host:port
./termarkable ssh user@host -i ~/.ssh/id_ed25519
./termarkable ssh user@host -p password

CLI options

Flag Description
--fb <path> Framebuffer device (default: /dev/fb0)
--font-size <px> Font size in pixels (default: 24)
--no-xochitl Don't stop/restart the stock UI on launch/exit

Controls

Input Action
Arrow keys / j/k Navigate menu
Enter Select / confirm
Escape Back to menu
Swipe up/down Scroll terminal history
Ctrl+C Send interrupt

Tailscale + Remote tmux

Set up Tailscale on the Paper Pro to SSH out to machines on your tailnet, with a persistent tmux session that survives disconnects.

Prerequisites

  • A Tailscale account with at least one other machine on your tailnet
  • Developer Mode enabled on the Paper Pro
  • SSH access to the device (USB: ssh root@10.11.99.1)
  • tmux installed on the remote host you want to connect to

How it works

The Paper Pro runs Codex Linux (aarch64) with a read-only rootfs and no /dev/net/tun, so Tailscale runs in userspace networking mode. The device ships with Dropbear (not OpenSSH), so outbound SSH uses dbclient with tailscale nc as a proxy. A helper script wraps this into a single tmux-connect command that creates or reattaches to a persistent tmux session on the remote host.

Paper Pro (termarkable shell)
  └─ tmux-connect
       └─ dbclient -J "tailscale nc <host> 22"
            └─ tmux new-session -A -s remarkable

1. Install Tailscale

The setup script downloads the latest stable Tailscale static binary for arm64, uploads it to the device, and installs the systemd service:

./setup-tailscale.sh             # USB default (10.11.99.1)
./setup-tailscale.sh <device-ip>

Then authenticate — scan the QR code or open the URL it prints:

ssh root@10.11.99.1 'tailscale up --qr'

Your device will appear on your tailnet. Verify with tailscale status.

What setup-tailscale.sh does
  1. Downloads the latest tailscale and tailscaled binaries for linux/arm64
  2. Uploads them to /home/root/tailscale/ (persistent encrypted partition)
  3. Remounts the rootfs read-write to create symlinks in /usr/bin and /usr/sbin
  4. Installs system/tailscaled.service to /usr/lib/systemd/system/ (on the rootfs, not the /etc tmpfs overlay)
  5. Creates the enable symlink on the rootfs by mounting the root device separately (bypassing the /etc overlay)
  6. Remounts the rootfs read-only and starts the service

The service runs in userspace networking mode with a SOCKS5 proxy on localhost:1055.

2. Generate an SSH key on the device

The Paper Pro ships with Dropbear, which uses its own key format:

ssh root@10.11.99.1 'dropbearkey -t ed25519 -f /home/root/.ssh/id_dropbear'

Extract the public key and add it to ~/.ssh/authorized_keys on the remote host(s) you want to reach:

ssh root@10.11.99.1 'dropbearkey -y -f /home/root/.ssh/id_dropbear'
# Copy the ssh-ed25519 ... line to the remote host's authorized_keys

3. Deploy the helper scripts

./setup-device.sh             # USB default (10.11.99.1)
./setup-device.sh <device-ip>

This installs two commands on the device:

Command Description
tssh user@host SSH to any host on your tailnet via tailscale nc
tmux-connect SSH + auto-attach to a persistent tmux session

4. Configure tmux-connect defaults

Create a config file on the device so tmux-connect works with no arguments:

ssh root@10.11.99.1 'cat > /home/root/tailscale/tmux-connect.conf << EOF
TMUX_DEST=user@your-tailnet-hostname
TMUX_SESSION=remarkable
EOF'

5. Use it

From the termarkable shell on the Paper Pro:

tmux-connect                       # attach to your default tmux session
tmux-connect user@other-host dev   # different host / session name
tssh user@some-host                # plain SSH

If you get disconnected (sleep, wifi drop, etc.), run tmux-connect again — it reattaches to the same session with all your work intact.

Persistence notes

  • Tailscale binaries live on /home (encrypted partition) and persist across reboots.
  • Binary symlinks (/usr/bin/tailscale, /usr/sbin/tailscaled, /usr/bin/tssh, /usr/bin/tmux-connect) are written to the rootfs and persist across reboots.
  • The systemd service is installed to /usr/lib/systemd/system/ on the rootfs with the enable symlink written directly to the rootfs (bypassing the /etc tmpfs overlay), so it persists across reboots.
  • Tailscale state (auth, node key) is stored in /home/root/tailscale/tailscaled.state and persists — you won't need to re-authenticate after a reboot.
  • Firmware updates replace the rootfs, so you'll need to re-run setup-tailscale.sh and setup-device.sh after a major OS update.

Architecture

src/
├── main.rs              CLI entry point (clap) and AppLoad backend detection
├── app.rs               Application state machine and async event loop
├── display/
│   ├── framebuffer.rs   /dev/fb0 mmap + MXCFB e-ink refresh ioctls
│   ├── font.rs          Font atlas (JetBrains Mono via fontdue)
│   └── renderer.rs      Terminal grid → pixel rendering
├── input/
│   ├── keyboard.rs      Type Folio evdev keyboard driver
│   └── touch.rs         Touchscreen gesture recognition
├── terminal/
│   └── handler.rs       alacritty_terminal wrapper and VT state
├── session/
│   ├── local.rs         Local PTY shell via nix
│   └── ssh.rs           Async SSH client via russh
└── ui/
    ├── status_bar.rs    Top status bar rendering
    └── menu.rs          Connection picker UI

Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.

License

Licensed under either of

at your option.

About

Terminal Emulator for the Remarkable Paper Pro

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages