Veil – Dark mode PDFs without destroying images, runs in the browser
Hi HN! here's a tool I just deployed that renders PDFs in dark mode without destroying the images. Internal and external links stay intact, and I decided to implement export since I'm not a fan of platform lock-in: you can view your dark PDF in your preferred reader, on any device. It's a side project born from a personal need first and foremost. When I was reading in the factory the books that eventually helped me get out of it, I had the problem that many study materials and books contained images and charts that forced me, with the dark readers available at the time, to always keep the…
In plain words
Veil is a browser-based tool that converts PDFs to dark mode while preserving image quality and maintaining all internal and external links. Designed for students, researchers, and anyone who reads PDFs in low-light conditions, it solves the common problem of images becoming unreadable when dark mode is applied. The tool allows users to export converted PDFs for viewing in any PDF reader on any device, avoiding vendor lock-in.
written from the facts on this page · September 2026
From the sources
In the maker’s words, at launch
Hi HN! here's a tool I just deployed that renders PDFs in dark mode without destroying the images. Internal and external links stay intact, and I decided to implement export since I'm not a fan of platform lock-in: you can view your dark PDF in your preferred reader, on any device. It's a side project born from a personal need first and foremost. When I was reading in the factory the books that eventually helped me get out of it, I had the problem that many study materials and books contained images and charts that forced me, with the dark readers available at the time, to always keep the original file in multitasking since the images became, to put it mildly, strange. I hope it can help some of you who have this same need. I think it could be very useful for researchers, but only future adoption will tell. With that premise, I'd like to share the choices that made all of this possible. To do so, I'll walk through the three layers that veil creates from the original PDF: - Layer 1: CSS filter. I use invert(0.86) hue rotate(180deg) on the main canvas. I use 0.86 instead of 1.0 because I found that full inversion produces a pure black and pure white that are too aggressive for prolonged reading. 0.86 yields a soft dark grey (around #242424, though it depends on the document's white) and a muted white (around #DBDBDB) for the text, which I found to be the most comfortable value for hours of reading. - Layer 2: image protection. A second canvas is positioned on top of the first, this time with no filters. Through PDF.js's public API getOperatorList(), I walk the PDF's operator list and reconstruct the CTM stack, that is the save, restore and transform operations the PDF uses to position every object on the page. When I encounter a paintImageXObject (opcode 85 in PDF.js v5), the current transformation matrix gives me the exact bounds of the image. At that point I copy those pixels from a clean render onto the overlay. I didn't fork PDF.js because It would have become a maintenance nightmare given the length of the codebase and the frequent updates. Images also receive OCR treatment: text contained in charts and images becomes selectable, just like any other text on the page. At this point we have the text inverted and the images intact. But what if the page is already dark? Maybe the chapter title pages are black with white text? The next layer takes care of that. - Layer 3: already-dark page detection. After rendering, the background brightness is measured by sampling the edges and corners of the page (where you're most likely to find pure background, without text or images in the way). The BT.601 formula is used to calculate perceived brightness by weighting the three color channels as the human eye sees them: green at 58.7%, red at 29.9%, blue at 11.4%. These weights reflect biology: the eye evolved in natural environments where distinguishing shades of green (vegetation, predators in the grass) was a matter of survival, while blue (sky, water) was less critical. If the average luminance falls below 40%, the page is flagged as already dark and the inversion is skipped, returning the original page. Presentation slides with dark backgrounds stay exactly as they are, instead of being inverted into something blinding. Scanned documents are detected automatically and receive OCR via Tesseract.js, making text selectable and copyable even on PDFs that are essentially images. Everything runs locally, no framework was used, just vanilla JS, which is why it's an installable PWA that works offline too. Here's the link to the app along with the repository: https://veil.simoneamico.com | https://github.com/simoneamico-ux-dev/veil I hope veil can make your reading more pleasant. I'm open to any feedback. Thanks everyone
Does the same job
all alternatives →- DRDark Reader extension – Dark mode for every website2018 · darkreader.org · ▲369

- PCpdfdark.com – view pdf's in "dark mode" all on client2025 · pdfdark.com · ▲22
I wanted a way to read PDFs at night and not burn my retinas out so I whipped together this super simple website with Claude to solve my problem. It uses Mozilla's pdf.js library to load and render a PDF and then inverts the colors with CSS. It has basic controls like zoom in, zoom out, reset zoom, previous and next page. There are some keyboard shortcuts that you can find by toggling the "q" key.

- UAUnclutter — A new approach to reader mode2022 · unclutter.lindylearn.io · ▲49
Hey! This is a reader mode browser extension I built that hides noisy page elements rather than extracting and re-rendering only the page text. The idea is to not make all articles look the same [0], have them still render graphs, and ideally to work in more cases. There are a few "tricks": patching the site CSSOM to apply simpler mobile styles even at desktop width, detecting the likely main text & removing its non-text siblings, blocklists for classnames that contain words like "sidebar", and testing this on a few hundred popular sites. I got carried away and also added a dark mode, page…

More work this month
the category →


The app store for voice native apps that lives in your notch
Work · 28d ago · voiceos.com


Mac-native app for screenshots, recordings and collaboration
Work · 5d ago · cleanshot.com
Launched alongside, March 2026
the whole month →

Switch from ChatGPT to Claude with import memory feature
AI · Mar 2026 · claude.com


