A private, minimalist native macOS PDF reader with smooth rotation and original-file protection. Created by Nikhil Sharma.
Swift
0
2 commits
updated Oct 13, 2026
A private, minimalist PDF reader for macOS, created by Nikhil Sharma with OpenAI ChatGPT models.
Version 1.8.1 · Last updated October 13, 2026 · macOS 14 or later
Download version 1.8.1 for Apple silicon, or build from source below. The app requires macOS 14 or later. Extract the ZIP and place Jack’s PDF.app in Applications, replacing an older copy if present.
The downloadable app is ad-hoc signed, not notarized by Apple. macOS may block a downloaded copy; follow Apple’s guidance for apps from outside the App Store only if you trust this release, or build it locally. Do not disable Gatekeeper globally. An Intel release has not been validated.
Open the app and choose Open PDF…, or use Finder's Open With → Jack's PDF. The app has one window and displays one PDF at a time. Opening another PDF replaces the current one without a rotation warning. Unsaved rotations are discarded only after the next PDF loads successfully; returning to the previous file shows its original orientation.
.pdf files in that folder only, in natural filename order (2.pdf before 10.pdf). Hidden files, symbolic links, packages and subfolders are excluded.The app offers no printing, sharing, cloud-upload, document-properties, annotation-editing or form-filling commands. Text can be selected and copied when the PDF permits copying. Embedded PDF actions and links are not activated.
Recent-file names, paths and permission bookmarks are stored in an AES-256-GCM encrypted file in the app container’s Application Support folder. The random encryption key is held in the local macOS login Keychain with access restricted to the creating app. The app does not request Keychain cloud syncing. Old preferences are removed only after encrypted migration is verified. A missing key or damaged store is preserved and reported, with no plaintext persistence fallback.
Ad-hoc signed updates may require macOS Keychain approval because the app’s code identity changes. Approve the system prompt only for an update you trust. The app retains ten recent PDFs and up to 10,000 folder approvals; it activates folder access only while needed. These records have no time-based expiry. Clearing is normal logical deletion, not a guarantee of secure erasure from disk or old backups. Encryption does not hide the open app’s UI or protect against an attacker controlling the unlocked app/process.
At startup, Jack’s PDF reads only its own history-encryption key from the local login Keychain. It holds that key in memory for the session; opening PDFs, approving folders, rotating pages and clearing history do not perform another Keychain read. Clearing history retains the encryption key.
macOS may show an approval or unlock prompt when:
A fresh installation normally creates its own key without an access-approval prompt when the login Keychain is unlocked. The app does not request your Apple ID password or access to unrelated passwords. If access is denied, reading remains available, but saved history and folder approvals cannot be loaded or reliably retained; existing encrypted data is preserved. Restart after approving access. If the key is missing while encrypted history exists, the app reports that error rather than silently replacing it.
Apple explains one-time versus ongoing permission, renewed approval for changed apps, and locked login Keychains.
In Finder, select any PDF and choose File → Get Info. Expand Open with, select Jack’s PDF, then click Change All and confirm if prompted. This changes the default for PDFs on this Mac. The app does not change that system preference itself. The app supplies its colourful icon for PDF documents. Finder may show this document icon when Jack’s PDF is the chosen PDF app; content thumbnails and custom file icons can take precedence. Thumbnail settings are left unchanged. See Apple’s instructions.
Click Rotate to turn the current page 90° clockwise. The adjacent arrow offers Rotate current page and Rotate all pages. Turns use a smooth 600 ms clockwise animation with subtle perspective and shadow movement, respecting the Mac's Reduce Motion setting. Repeated clicks continue clockwise through full turns. Four turns restore the original orientation.
Choose File → Save As… after rotating. The standard save dialog starts in the original folder with a suggested new filename. The original file is always protected, including alternate paths and hard links to it. Other existing destination files may be replaced after the standard confirmation. Unsaved rotations prompt Save As / Discard / Cancel only when quitting the app or closing its window. Switching PDFs with the arrows, Open or Open Recent, and choosing Close PDF, do not show that warning. These actions discard unsaved rotations without modifying the original.
Rotation uses native PDF page orientation rather than rasterizing the document. Export disables image downsampling and JPEG conversion and preserves native text/vector content. The tests check generated vector/text/form PDFs and a scanned JPEG fixture, including unchanged decoded image pixels and unchanged source bytes. These checks are not a guarantee for every unusual PDF or digital-signature workflow.
Password-protected PDFs can be opened with their password. Rotated export of encrypted PDFs is currently unavailable because the app does not silently remove or weaken their protection. Passwords are not written to history.
The nonresizable About dialog shows its complete contents without scrolling, using compact vertical spacing and the same 13-point text. It starts with the centred app icon and a text divider, followed by the app name and description, creator and model credits, update date and version. Text dividers separate the title, description, credits and tribute, followed by the unchanged photograph of Jack in a small, centred rounded frame. The tribute reads: “In loving memory of Jack, our sweetest companion and forever friend. You are still in our hearts and our lives every day.”
Install Xcode with its macOS SDK, then run from this directory:
./build.sh
open "build/Jack's PDF.app"
The script uses /Applications/Xcode.app/Contents/Developer unless DEVELOPER_DIR is already set. It builds for the current Mac's architecture (arm64 on Apple silicon), uses release optimization, and creates a locally ad-hoc-signed app with App Sandbox and the hardened runtime. It does not use an Apple ID, Developer ID certificate, provisioning profile or signing team.
Optional build settings:
BUILD_DIR="/absolute/path/to/build" ./build.sh
ARCH=arm64 ./build.sh
The build output is local and is not notarized for public binary distribution. Nothing is uploaded or published by the build script. Native Swift, AppKit and PDFKit supply the application and rendering; there is no Rust dependency or third-party runtime.
./test.sh
This compiles and runs three independent executables in build/tests (or $BUILD_DIR/tests). DocumentSupportTests checks source protection, exports, vector/text/forms, scanned-image preservation, invalid destinations, password handling, history, natural folder order and snapshot cleanup. ReaderViewTests checks native layout, fit and manual zoom, rotation, scrolling, read-only forms/accessibility, and blocked print/action/context-menu paths. The reader checks need a normal macOS graphical login session, and briefly show a generated-document window for animation checks.
EncryptedLibraryTests checks migration, authenticated encryption, tampering/wrong-key failures, private file modes, fresh nonces, 10,000-folder capacity, least-recently-used eviction, durable clearing and shortcut mapping. It injects an ephemeral key and never uses the user’s Keychain.
Tests create their own PDF fixtures. They do not use personal documents. They are functional checks, not a performance benchmark or a substitute for trying representative PDFs in the signed app.
See SECURITY.md for local storage, file access and original-file safeguards. The app contains no telemetry, tracking, network entitlement or automatic updater. The source contains Nikhil Sharma's creator credit; publishing it does not require adding account or signing details.
Released under the MIT licence. Copyright © 2026 Nikhil Sharma. The repository includes the intended app artwork and memorial photo; camera and editing metadata has been removed from the public photo without changing its decoded pixels.
The app uses an APFS copy-on-write snapshot when available, keeping the original separate without reading the entire PDF into RAM. Unsupported filesystems use a background copy with a 1 MiB buffer. PDFKit renders the file-backed snapshot on demand. An optional generated 200 MiB snapshot/isolation test can be run with PDF_LARGE_SNAPSHOT_TEST=1 ./test.sh.
A private, minimalist native macOS PDF reader with smooth rotation and original-file protection. Created by Nikhil Sharma.
Swift
0
2 commits
updated Oct 13, 2026
A private, minimalist PDF reader for macOS, created by Nikhil Sharma with OpenAI ChatGPT models.
Version 1.8.1 · Last updated October 13, 2026 · macOS 14 or later
Download version 1.8.1 for Apple silicon, or build from source below. The app requires macOS 14 or later. Extract the ZIP and place Jack’s PDF.app in Applications, replacing an older copy if present.
The downloadable app is ad-hoc signed, not notarized by Apple. macOS may block a downloaded copy; follow Apple’s guidance for apps from outside the App Store only if you trust this release, or build it locally. Do not disable Gatekeeper globally. An Intel release has not been validated.
Open the app and choose Open PDF…, or use Finder's Open With → Jack's PDF. The app has one window and displays one PDF at a time. Opening another PDF replaces the current one without a rotation warning. Unsaved rotations are discarded only after the next PDF loads successfully; returning to the previous file shows its original orientation.
.pdf files in that folder only, in natural filename order (2.pdf before 10.pdf). Hidden files, symbolic links, packages and subfolders are excluded.The app offers no printing, sharing, cloud-upload, document-properties, annotation-editing or form-filling commands. Text can be selected and copied when the PDF permits copying. Embedded PDF actions and links are not activated.
Recent-file names, paths and permission bookmarks are stored in an AES-256-GCM encrypted file in the app container’s Application Support folder. The random encryption key is held in the local macOS login Keychain with access restricted to the creating app. The app does not request Keychain cloud syncing. Old preferences are removed only after encrypted migration is verified. A missing key or damaged store is preserved and reported, with no plaintext persistence fallback.
Ad-hoc signed updates may require macOS Keychain approval because the app’s code identity changes. Approve the system prompt only for an update you trust. The app retains ten recent PDFs and up to 10,000 folder approvals; it activates folder access only while needed. These records have no time-based expiry. Clearing is normal logical deletion, not a guarantee of secure erasure from disk or old backups. Encryption does not hide the open app’s UI or protect against an attacker controlling the unlocked app/process.
At startup, Jack’s PDF reads only its own history-encryption key from the local login Keychain. It holds that key in memory for the session; opening PDFs, approving folders, rotating pages and clearing history do not perform another Keychain read. Clearing history retains the encryption key.
macOS may show an approval or unlock prompt when:
A fresh installation normally creates its own key without an access-approval prompt when the login Keychain is unlocked. The app does not request your Apple ID password or access to unrelated passwords. If access is denied, reading remains available, but saved history and folder approvals cannot be loaded or reliably retained; existing encrypted data is preserved. Restart after approving access. If the key is missing while encrypted history exists, the app reports that error rather than silently replacing it.
Apple explains one-time versus ongoing permission, renewed approval for changed apps, and locked login Keychains.
In Finder, select any PDF and choose File → Get Info. Expand Open with, select Jack’s PDF, then click Change All and confirm if prompted. This changes the default for PDFs on this Mac. The app does not change that system preference itself. The app supplies its colourful icon for PDF documents. Finder may show this document icon when Jack’s PDF is the chosen PDF app; content thumbnails and custom file icons can take precedence. Thumbnail settings are left unchanged. See Apple’s instructions.
Click Rotate to turn the current page 90° clockwise. The adjacent arrow offers Rotate current page and Rotate all pages. Turns use a smooth 600 ms clockwise animation with subtle perspective and shadow movement, respecting the Mac's Reduce Motion setting. Repeated clicks continue clockwise through full turns. Four turns restore the original orientation.
Choose File → Save As… after rotating. The standard save dialog starts in the original folder with a suggested new filename. The original file is always protected, including alternate paths and hard links to it. Other existing destination files may be replaced after the standard confirmation. Unsaved rotations prompt Save As / Discard / Cancel only when quitting the app or closing its window. Switching PDFs with the arrows, Open or Open Recent, and choosing Close PDF, do not show that warning. These actions discard unsaved rotations without modifying the original.
Rotation uses native PDF page orientation rather than rasterizing the document. Export disables image downsampling and JPEG conversion and preserves native text/vector content. The tests check generated vector/text/form PDFs and a scanned JPEG fixture, including unchanged decoded image pixels and unchanged source bytes. These checks are not a guarantee for every unusual PDF or digital-signature workflow.
Password-protected PDFs can be opened with their password. Rotated export of encrypted PDFs is currently unavailable because the app does not silently remove or weaken their protection. Passwords are not written to history.
The nonresizable About dialog shows its complete contents without scrolling, using compact vertical spacing and the same 13-point text. It starts with the centred app icon and a text divider, followed by the app name and description, creator and model credits, update date and version. Text dividers separate the title, description, credits and tribute, followed by the unchanged photograph of Jack in a small, centred rounded frame. The tribute reads: “In loving memory of Jack, our sweetest companion and forever friend. You are still in our hearts and our lives every day.”
Install Xcode with its macOS SDK, then run from this directory:
./build.sh
open "build/Jack's PDF.app"
The script uses /Applications/Xcode.app/Contents/Developer unless DEVELOPER_DIR is already set. It builds for the current Mac's architecture (arm64 on Apple silicon), uses release optimization, and creates a locally ad-hoc-signed app with App Sandbox and the hardened runtime. It does not use an Apple ID, Developer ID certificate, provisioning profile or signing team.
Optional build settings:
BUILD_DIR="/absolute/path/to/build" ./build.sh
ARCH=arm64 ./build.sh
The build output is local and is not notarized for public binary distribution. Nothing is uploaded or published by the build script. Native Swift, AppKit and PDFKit supply the application and rendering; there is no Rust dependency or third-party runtime.
./test.sh
This compiles and runs three independent executables in build/tests (or $BUILD_DIR/tests). DocumentSupportTests checks source protection, exports, vector/text/forms, scanned-image preservation, invalid destinations, password handling, history, natural folder order and snapshot cleanup. ReaderViewTests checks native layout, fit and manual zoom, rotation, scrolling, read-only forms/accessibility, and blocked print/action/context-menu paths. The reader checks need a normal macOS graphical login session, and briefly show a generated-document window for animation checks.
EncryptedLibraryTests checks migration, authenticated encryption, tampering/wrong-key failures, private file modes, fresh nonces, 10,000-folder capacity, least-recently-used eviction, durable clearing and shortcut mapping. It injects an ephemeral key and never uses the user’s Keychain.
Tests create their own PDF fixtures. They do not use personal documents. They are functional checks, not a performance benchmark or a substitute for trying representative PDFs in the signed app.
See SECURITY.md for local storage, file access and original-file safeguards. The app contains no telemetry, tracking, network entitlement or automatic updater. The source contains Nikhil Sharma's creator credit; publishing it does not require adding account or signing details.
Released under the MIT licence. Copyright © 2026 Nikhil Sharma. The repository includes the intended app artwork and memorial photo; camera and editing metadata has been removed from the public photo without changing its decoded pixels.
The app uses an APFS copy-on-write snapshot when available, keeping the original separate without reading the entire PDF into RAM. Unsupported filesystems use a background copy with a 1 MiB buffer. PDFKit renders the file-backed snapshot on demand. An optional generated 200 MiB snapshot/isolation test can be run with PDF_LARGE_SNAPSHOT_TEST=1 ./test.sh.