Running the reMarkable desktop app on Linux with Wine: what works, what breaks, and why
October 2026. Tested on one machine; every claim below is backed by raw data I kept while testing, and anything I didn't test is marked as such.
reMarkable makes desktop apps for Windows and macOS, and none for Linux. I wanted to know whether the Windows app could be made genuinely pleasant under Wine — not "it launches", but signing in, syncing, importing, exporting, the clipboard, Screen Share and the tablet on USB — and, where something didn't work, why, from first principles.
The short version: it works well, after four registry settings. Along the way I found a Wine behaviour that silently swallows Qt's environment variables, a renderer thread that burns 40% of a core, a "No cloud connection" banner that can never appear, a Windows-only tablet recovery tool hidden in the Help menu, and a laptop that quietly starves a tethered tablet to death overnight.
The setup: Ubuntu 26.04.1 (kernel 7.0), Wine 10.0 from Ubuntu's archive, a Framework Laptop 13 (Ryzen 7 7840U, Radeon 780M, Mesa 26.0.8), GNOME on Wayland at 133% scaling. The app is reMarkable 3.29.0.1804 for Windows (Qt 6.10.3); the tablet is a reMarkable Paper Pro Move.
Why bother?
Fair question. The web app (app.remarkable.com) now covers a lot: your library, uploads (PDF, EPUB, images, Word/Google Docs/text), share links, and Screen Share (tablet software 3.27 or newer). If that's all you need, use it.
What the desktop app adds:
- Editing and typing in notebooks (needs a Connect subscription), and handwriting-to-text conversion.
- A local copy of your library, export to PDF/PNG/SVG, and no 100 MB import cap.
- Desktop integration: drag and drop, "Open With", the clipboard.
The Android app in Waydroid is another route; I didn't test it.
The minimal setup
Four settings do all the work. Everything else in this post is optional polish.
export WINEPREFIX=~/.wine-remarkable
# 1. Install headless. --root is required: the default target (/reMarkable) is rejected under Wine.
# The override avoids the installer crash on Wine 10.0 (see below).
WINEDLLOVERRIDES="windows.networking.connectivity=d" \
wine reMarkable-3.29.0.1804-win64.exe install --root 'C:\Program Files\reMarkable' \
--accept-licenses --default-answer --confirm-command
# 2. Keep that override for the app and for future auto-updates (Wine 10.0 only — see below)
wine reg add 'HKCU\Software\Wine\DllOverrides' /v windows.networking.connectivity /d '' /f
# 3. Use Qt's OpenGL renderer for every process in the prefix
wine reg add 'HKCU\Environment' /v QSG_RHI_BACKEND /d opengl /f
# 4. HiDPI only: match Wine's DPI to what X11 apps see (xrdb -query | grep Xft.dpi)
wine reg add 'HKCU\Control Panel\Desktop' /v LogPixels /t REG_DWORD /d 192 /fThen start C:\Program Files\reMarkable\reMarkable.exe, click Get a new code, find the browser tab (on Wayland it opens behind your windows, so it looks like nothing happened), and paste the code back.
Two things not to do: don't disable netprofm (sign-in breaks — see below), and don't bother with DXVK, the Wine Wayland driver or the WebView2 runtime.
The prefix ends up at about 1.8 GB (1.1 GB of that is Wine itself); the running app uses roughly 670 MB of RAM, about 880 MB with Wine's helper processes, and idles at 0.2–0.3% CPU.
What broke, and why
1. The installer crashes on Wine 10.0
The installer dies with a page fault at address 0 right after loading Wine's WinRT network-information component. The app asks WinRT for an IConnectionProfile2 interface, Wine 10.0's stub answers E_NOINTERFACE, and the code dereferences the null result.
This is WineHQ bug 57529 — a regression after Wine 9.22, fixed in Wine 10.1. Ubuntu 26.04 (like Debian 13) ships 10.0, which predates the fix. Disabling just windows.networking.connectivity gets past it. On Wine 11 (Fedora, Arch, WineHQ's packages, Flathub) you can probably skip the override; I haven't tested that.
2. Ghosts, then a 40% CPU burn
Qt 6 renders through Direct3D 11 on Windows. Through Wine's built-in translation layer (wined3d), the window showed stale frames and "ghosts" of earlier states. Through DXVK, it rendered correctly — but one thread used 40% of a CPU core while the app sat idle.
Disassembling Qt6Gui.dll at the busy thread's return address shows the culprit: Qt's vsync helper (QDxgiVSyncThread) in a loop around IDXGIOutput::WaitForVBlank. DXVK can't get a real vertical-blank signal under Wine, so its WaitForVBlank estimates the interval and busy-waits; with Wine's 1 ms timer that predicts about 40.7% of a core — I measured 40.4%. Wine's own dxgi simply reports "not implemented", so Qt sleeps instead, which is why wined3d idled at 0.7%.
| Render path | Idle CPU | Display |
|---|---|---|
| D3D11 via wined3d | 0.7% | ghosting |
| D3D11 via DXVK | 40% | correct |
| D3D11 via DXVK + vsync thread off | 0% | correct (smoothness not compared) |
OpenGL (QSG_RHI_BACKEND=opengl) | 0.2% | correct |
The OpenGL backend sidesteps all of it, and it uses the real GPU (Mesa's radeonsi). That's the recommended setting.
3. Wine silently drops QT_* environment variables
Qt has a switch for that vsync thread, QT_D3D_NO_VBLANK_THREAD=1. I set it and nothing changed — still 40%. The binary contains the check and its log message, so why?
I read the flag straight out of the running process with winedbg: it was 0. Then:
$ QT_FOO=1 ABC_FOO=1 QSG_INFO=1 wine cmd /c set | grep -E '^(QT|ABC|QSG)'
ABC_FOO=1
QSG_INFO=1
$ WINEQT_FOO=1 wine cmd /c set | grep ^QT
QT_FOO=1Wine doesn't pass Linux environment variables that start with QT_ to Windows programs. It's deliberate — is_special_env_var() in Wine's ntdll filters QT_ (since 2016), VK_, XDG_SESSION_TYPE and, in Wine 11, a few more, so your desktop's Qt settings don't leak into Windows apps that bundle their own Qt. The escape hatch is the WINE prefix: WINEQT_D3D_NO_VBLANK_THREAD=1 arrives as QT_D3D_NO_VBLANK_THREAD=1. With that, the flag reads 1 and idle CPU drops to 0%. Values in the prefix's HKCU\Environment aren't filtered either.
Two lessons. First, if a Qt variable "does nothing" under Wine, this is why. Second, checking /proc/<pid>/environ proves nothing: it shows the Linux-side environment, not what Windows code sees. That fooled me.
4. Sign-in: "Could not receive hostname: Network Error"
My first instinct had been to disable both Wine's WinRT network component and netprofm. With netprofm gone, Qt's network-status backend fails to load, the app concludes it's offline, and it refuses to even try a DNS lookup (I checked with WINEDEBUG=+winsock: no lookup happens). Re-enabling netprofm fixed sign-in. (I had also added Qt's OpenSSL TLS plugin along the way; it wasn't the fix, and you don't need it.)
5. HiDPI: a 2× screen that isn't
The laptop panel is 2256×1504 (about 200 PPI) at GNOME's 133%. But X11 apps — and so Wine — see a 3384×2256 screen with Xft.dpi 192: with xwayland-native-scaling, mutter gives X11 clients the next integer scale (2×) and then shrinks the result by 0.667 to fit the panel.
Wine has a single global DPI (LogPixels) defaulting to 96, so the app was tiny. 192 matches GNOME's sizes exactly; I settled on 144, which renders the app at 75% of that and suits me. Two consequences: the downscale can soften text slightly, and per-monitor DPI isn't possible on Wine's X11 driver — a second monitor at a different scale will be wrong.
Wine's Wayland driver avoids XWayland entirely, but on Wine 10 it gave me blurrier text, a disappearing title bar when maximized and no speed-up, and it lacks clipboard and drag-and-drop support. Not yet.
Living with it
Getting files in
- Import button, drag and drop from Files: both work. Imported PDFs are stored byte-for-byte unchanged.
- "Open With reMarkable" needs a small launcher. Two quirks: a cold-started app ignores file arguments (only a running instance accepts files handed over by a second launch), and a bare
/home/...path is resolved against the app's current drive — which breaks if you map a drive letter to your home folder. The launcher starts the app, waits for its window, then hands overwinepath -wpaths.
Getting files out — and why the PDF name is always blank
Export uses Wine's file dialog, which is functional but plain: no address bar, and it opens on Wine's virtual "Desktop". Two things looked like Wine bugs and weren't.
I unpacked the app's own interface code (QML, compressed inside reMarkable.exe). The export function pre-fills <document name>.pdf only when running on macOS; on Windows it passes just the Desktop folder. So the blank file name happens on real Windows too. PNG/SVG exports open a folder picker pointed at Desktop/<document name> — a folder that doesn't exist yet — so the dialog falls back to its root view, and the app then silently creates <name>/<name> - page N.png wherever you click.
The fix needed no code at all: the app's "Desktop" is just a symlink inside the Wine prefix (drive_c/users/<you>/Desktop). Point it at an exports folder and every export dialog opens there, while your real Desktop stays clean. Adding links under the prefix's Favorites folder gives one-click access to Documents, Downloads and home.
Could Qt's own, nicer dialogs be used instead? WINEQT_QPA_PLATFORM=windows:dialogs=none (note the WINE prefix — see above) does switch Import to Qt Quick's scalable dialog. But Export then can't open any dialog at all, and Qt says why in the log: "Qt Labs Platform requires Qt Widgets on this setup." The export screen uses Qt.labs.platform, whose fallback needs Qt Widgets, and this app doesn't create a Widgets application. I made it an opt-in launcher mode (remarkable --qt-dialogs) for import-heavy sessions.
Export output, for the record: PDF export keeps the original PDF (and its own annotations) and adds your handwriting as vector graphics; PNG is 1136×1589 for a 5×7-inch page; SVG isn't fully vector — the page background is an embedded PNG and only the ink is vector paths.
The clipboard
Plain text works both ways. Rich text (HTML) is translated into reMarkable's text model: headings, bold, italic and two levels of bullets survive. Underline, strike-through, colour, links and tables don't.
Numbered lists are the interesting case. Decoding the notebook file shows reMarkable does store a pasted <ol> as numbered-list paragraphs — but neither the desktop app nor the tablet displays the numbers. And when Firefox copies part of a list, it doesn't even include the <ol>: it puts that context in a separate, Firefox-only clipboard format, encoded as UTF-16. My clipboard helper rewrites numbered items as literal 1., 2. text before you paste; that's the only numbering that shows.
(Images and text paste only onto a blank added page, not onto PDF or template pages — that's the app, not Wine.)
Screen Share works
Start it from the tablet; the desktop app accepts. It's WebRTC (libdatachannel) over Wine's sockets, and it just works.
The offline banner that can never appear
During an airplane-mode test, the app never told me it was offline; it just retried with growing back-off. The QML has a "No cloud connection" bar bound to Qt's online status, so why not?
The undocumented RM_LOG_FILE variable (more below) gives the app's own log, which shows Qt failing to register its WinRT network-change listener — because of the override from section 1. Its other listener, via netprofm, registers fine, but Wine's implementation never fires change events: it takes a snapshot at startup. Both doors are shut, so the app never hears that the network changed. I'd expect an app started offline to stay "offline" until restarted (untested).
Content: PDFs and EPUBs made on Linux
Annotations that vanish
GNOME's Document Viewer (Papers, Poppler-based) saves annotations without appearance streams (/AP) and without the "print" flag. reMarkable renders with PDFium, which draws ink and highlights from scratch, but never shows a sticky note's text and drops free-text boxes without /AP entirely.
reMarkable's own advice is to "print" an annotated PDF to a new file. The Ghostscript equivalent:
gs -dSAFER -o flat.pdf -sDEVICE=pdfwrite -dPreserveAnnots=false -dShowAnnots=true -dPrinted=false in.pdf-dPrinted=false is the non-obvious part: with print semantics, Ghostscript drops exactly the annotations Papers wrote, because they lack the print flag. A caution: Ubuntu's current Ghostscript package doesn't yet include the fix for CVE-2026-101258 (a -dSAFER bypass, fixed upstream in 10.08.0). Only run this on PDFs you trust, and only on files that really are PDFs.
EPUBs with Chinese, Japanese or Korean text
An EPUB without embedded fonts showed 日本語 as three empty boxes — on the tablet and the desktop app alike. Neither EPUB renderer has a CJK fallback font. Embedding a CJK-capable TTF via @font-face fixed it everywhere, even for paragraphs styled with a generic serif: the embedded font becomes the fallback for any glyph the renderer lacks. Use a .ttf/.otf, not a .ttc collection.
The tablet over USB
Plug a Paper Pro Move into Linux and it appears as a USB network adapter; the tablet is at 10.11.99.1. With Settings → Storage → USB web interface on, port 80 serves a small, unauthenticated JSON API:
| Call | What it does |
|---|---|
GET /documents/ and /documents/<folder-id> | List a folder — and make it the "current folder" for uploads |
GET /download/<id>/pdf | PDF with handwriting and annotations |
GET /download/<id>/rmdoc | The native document, original PDF included byte-for-byte: a lossless backup |
POST /upload (multipart field file) | PDF, EPUB or rmdoc, up to 100 MB; text and images are refused |
GET /log.txt | The tablet's entire system journal |
A full backup of 94 documents (164 MB) took 51 seconds with curl. One privacy note: the page the tablet serves to your browser loads Sentry, with session replay and network-detail capture enabled for these URLs. Reading the code, document listings and request contents may be sent to reMarkable's error-tracking service; using the API from a script avoids that.
The journal is the best diagnostic you'll get
On the Paper Pro family, SSH requires developer mode, which factory-resets the device. But /log.txt — 15 MB, about four weeks — told me nearly everything:
- Wi-Fi had been down for three weeks because I'd replaced my router with one using the same network name. Forgetting the network and re-entering the password fixed it in seconds — and it then installed an update it had been missing (3.28.0.172).
- A crash report had been deleted unsent after five failed upload attempts while offline.
- The "shutdown at 11%" was by design: the tablet keeps a hidden 10% reserve (
userAvailable=0 realAvailable=10).
A sleeping laptop starves the tablet
The most surprising finding. I left the tablet plugged into the laptop overnight with the lid closed; by lunchtime it had shut down, its charger still listed as "connected".
The two logs line up to the second. The tablet charged from 38% to 82% at 1500 mA. The laptop entered suspend at 18:30:36; one second later the tablet's charge controller dropped to 100 mA — the USB minimum — and stayed there. The tablet's screen went to light sleep, but with a charger connected it postponed deep sleep once a minute, 1,094 times, never suspending, and drained about 4% an hour until it shut down at its 10% reserve. On a normal unplugged night it reaches deep sleep within half an hour.
Lesson: charge from a wall adapter, or unplug before closing the lid.
What's inside the app
- It's built from the tablet's own codebase. The binary carries 194 build paths from reMarkable's
xochitlrepository, and the desktop registry even stores aDeveloperPassword— a tablet-only SSH setting. The core libraries are shared; the user interface is a Qt Quick "client" layer shared with the phone apps. A native Linux build would be a packaging decision more than an engineering project. - All in-app web views are macOS-only. Sign-in and "Delete account" use an embedded web view on Mac; Windows opens your browser. The missing WebView2 runtime under Wine therefore changes nothing.
- The desktop app is also a recovery tool. Help → Recovery, visible only on Windows, walks you through resetting an unresponsive tablet over USB-C and runs a bundled
rm_recover.exe(reMarkable's recovery tools, built on NXP's flashing utility). I deliberately didn't test it under Wine; reMarkable publishes a native Linux build. - Undocumented switches.
RM_LOG_FILE='C:\rm.log'makes the app write its own log — the single most useful diagnostic for Wine problems.RM_BLOCK_UPDATESexists too (untested).
Going further: a Linux "sidecar"
Everything above that isn't a registry setting lives in an optional set of scripts I call the sidecar, wired in through standard desktop hooks: a launcher, a "Send to reMarkable" entry in Files, a watcher that renames exports to 2026-10-18 <title> p3.png, a clipboard helper, a USB tablet check that reads the journal and backs up when stale, and a warning if you suspend with the tablet attached. It never modifies your original files, installs without root, and identifies the tablet by its USB vendor ID rather than its IP address. I haven't published the scripts or their spec yet.
What can't work (yet), and the options
| Gap | Why | Options |
|---|---|---|
| Offline/online awareness | WinRT listener disabled for the installer bug; Wine's netprofm never fires events | Restart the app after reconnecting; on Wine 11, try without the override |
| Pre-filled export name | App code only does it on macOS | Type it; or a proxy DLL calling SetFileName (fragile) |
| Nicer file dialogs | Wine's dialog has no address bar; Qt's own dialog breaks Export | Favorites links and the Desktop remap; --qt-dialogs mode for imports |
| Per-monitor DPI | One global DPI on Wine's X11 driver | Choose for your main screen; Wayland driver later |
| Numbered lists in pasted text | Stored, but not displayed by reMarkable | Type the numbers (clipboard helper) |
| SSH without a factory reset | Paper Pro security model | USB API and /log.txt |
| Print to reMarkable | Not offered on any Linux path | A PDF printer plus a folder watcher that uploads over USB |
Still open
- Does Wine 11 run the app with no override at all — and does the offline banner then work?
- Is D3D11 via DXVK (with the vsync thread off) smoother than OpenGL?
- Does the tablet postpone sleep because of the charger, or because of the USB data link?
- NVIDIA GPUs, X11 sessions, two monitors at different scales, and Waydroid.
How I checked
Every claim here has an entry in an assumptions inventory with its status — re-verified from primary data, observed in the session, reported by a person at the screen, or documentation only — and the raw data behind it: registry exports (secrets removed), disassembly, process measurements, decoded notebook files, kernel logs and tablet journal excerpts. Four independent reviews, each playing a sceptical reader (a Wine expert, a privacy reviewer, someone replicating the setup and a reMarkable hacker), then attacked the draft. They caught real mistakes — my display-scaling arithmetic, the cause of the missing offline banner, and the claim that pasted numbered lists are simply discarded — all corrected above.