Skip to content
| Marketplace
Sign in
Visual Studio Code>Other>Dark Knight PDF — Dark Mode & HighlightsNew to Visual Studio Code? Get it now.
Dark Knight PDF — Dark Mode & Highlights

Dark Knight PDF — Dark Mode & Highlights

mingtian

|
1 install
| (0) | Free
Read PDFs in dark mode and save text highlights as portable PDF annotations.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

Dark Knight PDF — Dark Mode & Highlights

Read PDFs in VS Code, highlight selected text, and save annotations directly into the PDF.

Features

  • PDF.js viewer with continuous scrolling, page navigation, zoom, fit to width, and page rotation.
  • Click PDF links to follow named destinations, page references, and positions within pages. Internal links preserve the current zoom and enter the PDF's Alt+Left/Right location history. Web and email links open through VS Code.
  • Toggle Contents to show or hide a table of contents on the left. Child sections start collapsed. Expand chapters and click a bookmark to navigate using the same PDF-local history. The panel remembers its visibility and loads the outline only when opened. Only rows near the sidebar viewport are rendered, even for branches containing thousands of entries; hover a long title to read it in full. PDFs without bookmarks show an empty-state message.
  • Contents emphasizes the current reading section and scrolls it into view on page changes or when reopened. Sections expand only when you click their disclosure button; following never changes expansion states. If the precise current section is inside a collapsed branch, its nearest visible ancestor is marked instead. Pages without an exact bookmark use the preceding section; the deepest same-page bookmark takes precedence. Manual Contents scrolling stays in place while you remain on the same PDF page.
  • Press Ctrl+F / Cmd+F or click the magnifier to search PDF text. Matches are highlighted; Enter / Shift+Enter or F3 / Shift+F3 moves between results, Aa toggles case matching, and Escape closes search. Search markers are temporary and never saved as annotations.
  • Large-document search starts at the current page, scans progressively with a page counter, and prioritizes visible-page rendering. Stop cancels the remaining scan while retaining results already found. A + indicates a partial result count; refine the query if the 10,000-match limit is reached.
  • Dark reading mode by default, with a light mode toggle and a separate highlight overlay.
  • Select text and click + Highlight to apply yellow, green, blue, or pink highlights.
  • Highlights can span multiple lines and pages. Positions are stored in PDF coordinates.
  • Highlight sidebar with text excerpts, jump to highlight, and delete actions.
  • Highlights on the current reading page are emphasized in the sidebar, which automatically scrolls to them as you change pages. Manual sidebar scrolling stays in place until the reading page changes again.
  • Ctrl+S / Cmd+S saves standard PDF /Highlight annotations with appearance streams for display in compatible readers.
  • VS Code undo, redo, Save As, unsaved changes prompts, and backup recovery.
  • All viewer assets are bundled with the extension. No CDN, telemetry, or file uploads.
  • Virtualized continuous scrolling keeps only nearby page elements, canvases, and text layers mounted, including for manuals with tens of thousands of pages. Offscreen rendering is cancelled and canvas resolution has a per-page pixel limit.
  • Recently completed pages keep a detached return cache, so going back from a loading page restores the existing canvas, selectable text, links and highlights immediately. By default the cache holds up to 64 pages and 256 MiB of canvas data, allocated as you browse. Both limits are configurable and apply immediately to open readers; older entries are released when either limit is reached. Changes to rendered scale/rotation and document reloads invalidate the cache.
  • Saving preserves the current page and scroll position. Document reloads and width changes also retain the position within the page.
  • Large-document saves run in a separate worker, with a saving indicator, elapsed time, completion feedback, and error reporting. Annotation updates append only changed PDF objects rather than recompressing the entire document.
  • Reading starts before the full saved-highlight scan finishes. Existing native highlights remain visible while the sidebar loads in a background worker; highlight editing and saving become available when that scan completes. The PDF stays open at the same position, without a second viewer load. Closing the document cancels its background scan.

Development

Requires Node.js 22.13+, pnpm 10.26+, and VS Code 1.96+.

pnpm install
pnpm run check
pnpm run build
pnpm test

For browser integration tests, run pnpm exec playwright install chromium once, then run pnpm run test:ui. To use an existing browser, set the PDF_HIGHLIGHT_BROWSER environment variable to the path of your Chrome executable. On Windows, the test also detects Chrome in its default installation directory.

Run pnpm run test:regression to check long-document startup and scroll-position preservation using the downloaded 696-page RISC-V fixture in test/fixtures/riscv/. The test uses a temporary copy and leaves the original fixture unchanged.

Run pnpm run test:arm with the downloaded Arm A-profile manual in test/fixtures/arm/ to stress-test sustained scrolling across 17,150 pages, bounded page/canvas counts, distant page jumps, and the last page at 400% zoom. It reads the fixture without modifying it and writes measurements/screenshots under tmp/regression/. These are headless browser measurements; native VS Code performance also depends on the host and graphics driver.

Run pnpm run test:arm-save to additionally save an annotated copy to tmp/regression/arm-saved.pdf, verify that browsing remains responsive during saving, measure the appended bytes and save time, and reopen the native highlight with PDF.js. The original fixture is unchanged.

Run pnpm run test:arm-startup to separately measure host opening, first readable page, and saved-highlight loading on the Arm manual. It also verifies that loading existing highlights does not reload the viewer or create duplicate overlays. Headless startup timings exclude VS Code's own window/extension-host startup and should not be interpreted as a direct comparison with a native reader.

Run pnpm run test:arm-cache to delay loading a distant page, return to a previously read page and verify immediate reuse of the original canvas/text. It also checks cache eviction, pixel limits and invalidation after zoom, without modifying the Arm fixture.

On Windows, the optional native migration test can be started with powershell -File scripts/test-vscode.ps1 after building and running the regression test. It expects the original local-dev.pdf-highlight-dark extension to be installed so it can verify coexistence. The launcher uses an isolated test profile, redirects process output to files under tmp/vscode-native-tests/, and requires a fresh passing report. Avoid attaching a long-lived VS Code process with verbose console logging to a temporary tool output pipe; writing to a closed pipe can produce an Electron main-process EPIPE dialog. If VS Code is updating, let the update finish before retrying the native test.

Open this directory in VS Code and press F5 to launch the Extension Development Host. Open a PDF in the new window. If another PDF extension handles the file, right-click it and choose Open With… → Dark Knight PDF — Dark Mode & Highlights, or use Reopen Editor With….

Select text, choose a color, click + Highlight, and press Ctrl+S / Cmd+S to save. Saving updates the current PDF. Use VS Code's Save As… to preserve the original file.

pnpm run package
code --install-extension dark-knight-pdf-0.1.0.vsix --force

The Marketplace publisher ID is mingtian. Select that publisher when uploading the VSIX; it must match the publisher value in package.json.

Updating development builds

Development builds stay at version 0.1.0 until the first release. Use --force when installing an updated VSIX with the same version, then run Developer: Reload Window in VS Code.

For startup diagnostics, open View → Output and select PDF Dark Knight. The local log records file loading, viewer startup, worker loading, PDF parsing, and first-page rendering times, without document text or file paths. The PDF worker is loaded from a Blob to support VS Code's Webview restrictions; PDF bytes use binary message transport.

If you previously installed PDF Highlight & Dark Mode, an existing PDF tab may still use that old reader. Run PDF Dark Knight: Open Current PDF from the Command Palette, or right-click a PDF in Explorer and choose that command. The new reader uses its own pdfDarkKnight.editor identifier, so it can run alongside the old extension without registration conflicts. Confirm that the toolbar says PDF Dark Knight and that the footer shows a build ID. The build ID identifies the installed source without changing the version number.

Keyboard Shortcuts and Settings

Action Windows / Linux macOS
Highlight selection Ctrl+Alt+H Cmd+Alt+H
Toggle dark mode Ctrl+Alt+D Cmd+Alt+D
Find in this PDF Ctrl+F Cmd+F
Next / previous search result F3 / Shift+F3 F3 / Shift+F3
Next / previous result in the search field Enter / Shift+Enter Enter / Shift+Enter
Close PDF search Esc Esc
Previous reading location in this PDF Alt+Left Option+Left
Next reading location in this PDF Alt+Right Option+Right
Zoom PDF at mouse pointer Ctrl+mouse wheel Ctrl+mouse wheel
Save PDF Ctrl+S Cmd+S
Undo / redo Ctrl+Z / Ctrl+Shift+Z Cmd+Z / Cmd+Shift+Z

Settings: pdfDarkKnight.darkMode (default: true) and pdfDarkKnight.defaultColor (default: yellow). Existing pdfHighlight.* settings are used as fallbacks for these two settings when the corresponding new setting has not been explicitly set.

Return cache settings apply immediately without reloading the PDF:

Setting Default Range
pdfDarkKnight.pageCacheMemoryMB 256 MiB per PDF 0–1024 MiB
pdfDarkKnight.pageCacheMaxPages 64 pages per PDF 0–256 pages

Set either limit to 0 to disable the return cache. The memory limit covers cached canvas pixels, excluding active pages, text layers, PDF parsing and VS Code itself. For a larger cache, for example:

{
  "pdfDarkKnight.pageCacheMemoryMB": 512,
  "pdfDarkKnight.pageCacheMaxPages": 128
}

The Alt/Option arrow shortcuts use this PDF's location history while the PDF editor is active. Page-number jumps, page navigation buttons, and highlight sidebar jumps create history entries. Each entry keeps its position within the page, zoom, and rotation. Ordinary scrolling updates the current location without adding an entry for every scroll. Jumping somewhere new after going back discards forward history. Ctrl+wheel over the PDF zooms in or out in 10 percentage-point steps, from 25% to 400%, while keeping the PDF point under the mouse where scrolling limits allow.

Current Limitations

  • Scanned PDFs need an existing OCR text layer for text selection and search. This version does not perform OCR.
  • Highlights created by this extension are editable. Highlights from other readers are preserved and displayed, but are not included in the editable sidebar. Other annotations are preserved in the file without an interactive editing interface.
  • Dark mode inverts page images and chart colors. Saved PDFs retain their original page colors.
  • The rotation button changes the reading orientation without modifying the PDF's page rotation properties.
  • Encrypted or password-protected PDFs are not supported. Annotation saves modify the PDF, so this extension is not suitable for documents whose digital signatures must remain valid.
  • This version focuses on reading and highlighting. Freehand annotations and a print interface are not implemented yet. The Contents panel uses embedded PDF bookmarks; it does not infer an outline from printed contents pages. Search is literal text matching with Unicode compatibility normalization and collapsed whitespace, including phrases across lines on the same page; regular expressions and phrases spanning pages are not supported.

Implementation

VS Code's CustomEditorProvider manages document edits, saving, and backups. PDF.js renders pages and selectable text layers, while PDF-Lib writes standard highlight annotations. QuadPoints stores the position of each selected text fragment. Annotations created by this extension include private metadata to support subsequent editing; unrecognized annotations are preserved. Trusted viewer scripts and styles are cached in the extension host and embedded with a nonce to reduce first-paint resource requests. Local PDFs use direct host file reads; other URI schemes use VS Code's filesystem API.

Page positions use a numeric prefix-sum index with logarithmic lookup and height corrections, avoiding document-wide DOM scans during scrolling. A single render scheduler prioritizes the current page. Physical scrollbar height is capped at four million CSS pixels and adjusted to the measured spacer height for Webview engines with smaller layout limits. Mounted content cannot enlarge that extent. Logical positions retain a rounding correction so high-DPI scrolling and pointer-anchored zoom remain precise; page content keeps its actual scale and mouse-wheel scrolling keeps screen-pixel speed. Active text selections retain their page elements until the selection is cleared.

Saving parses the document in a dedicated Node worker and appends changed page dictionaries, highlight annotations, appearance streams, and a cross-reference revision. Existing compressed object/xref stream numbers are reserved to avoid collisions. Documents recovered without a valid original startxref use an uncompressed full rewrite as a fallback. Reading saved highlights also removes their display copies with a small incremental update, avoiding a full-file recompression on reopen.

The interface and features are inspired by PDF Dark Mode. This project is an independent implementation.

The packaged extension includes the licenses for PDF.js (Apache-2.0) and PDF-Lib (MIT).

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
  • Your Privacy Choices
  • Consumer Health Privacy
© 2026 Microsoft