A few weeks ago I was reading "Attention Is All You Need" for probably the fifth time. It was late, I had the PDF open full screen, and within a few minutes, I realised my eyes weren't tired from the screen.
Everything on a Mac is so clean and glossy. White is really white. Every page looks like it's printed on glass. That's great for photos, but when you're reading for hours it starts to feel harsh, and I kept thinking about how much nicer the same paper would feel if it was, well, on paper.
So I went looking for an app that could fake that.
The apps that already exist
Turns out I'm not the first person to want this. There are a few apps that put a texture over your screen, and some of them look really good. But every one I found had the same problem for me: I couldn't try it without paying first.
One was around $13 upfront with no free version at all. Another was part of a bigger subscription bundle. For something this personal, where you can only know if you like it by living with it for a day, paying before trying felt wrong. A texture that looks lovely in screenshots might be annoying on your actual screen with your actual apps.
I'm a backend dev. I spend my days with Node, Redis and queues, not AppKit. But I'd been wanting to ship something of my own for a long time, and this felt small enough to actually finish. So I decided to build my own, with a free version anyone could just try.
That became Shoji, named after the Japanese paper screens that let soft light through.
How it actually works
The core idea is surprisingly simple. Shoji puts one borderless, transparent window on every display, floating above everything else, and draws a light paper texture into it. The important bit is that the window ignores the mouse completely, so every click goes straight through to whatever is underneath:
ignoresMouseEvents = true
level = NSWindow.Level(rawValue: Int(CGWindowLevelForKey(.assistiveTechHighWindow)))
collectionBehavior = [.canJoinAllSpaces, .stationary, .fullScreenAuxiliary, .ignoresCycle]
That last line is what lets it follow you across Spaces and sit over full screen apps too.
The part that took the longest wasn't the window though. It was the paper.
I didn't want to use photos of paper, because photos tile badly. You start seeing the same blotch repeat every few inches and your brain can't unsee it. So every texture is generated in code, using layered noise, a bit of domain warping so the patterns never line up in rows, and little randomly walked "fibers" for papers like Washi and Newsprint. It's all seeded, so the same paper looks the same every time, and it renders sharp on any display.
Getting them right in dark mode was its own adventure. Shadows that look like nice paper grain on white just disappear on a dark background, and fibers that look subtle on light mode suddenly look like hair on your screen in dark mode. I ended up with separate recipes for light and dark, and a separate strength setting for each, so dark apps stay dark.
A few other fun things I learned along the way:
-
Hiding from screenshots is one line,
sharingType = .none. Your screen shares and recordings stay clean. - Getting notarized was more stressful than writing the app. Xcode kept telling me I wasn't the account holder of the account I literally owned, and I got very familiar with keychain error codes.
- Auto updates run on Sparkle, and I found a fun bug where the update window would open behind Spotify and make the whole app look frozen. Lesson learned: always bring your app forward before showing a modal.
And then, before I'd even posted it anywhere except one tweet, someone bought it. A real person, who I don't know, paid for a thing I made. I'm not going to pretend I was calm about it.
What Shoji does
- 7 papers: Plain, Rice, Linen, Newsprint, Washi, Cold Press and Parchment
- Clicks pass through, so everything works exactly like before
- Every display, including external monitors and full screen apps
- Hidden from screenshots and screen recordings
- Separate strength for light and dark mode
- Pause it for 15 minutes, an hour, or until tomorrow
- Lives in your menu bar, with keyboard shortcuts to toggle it or switch papers
- No tracking. It never reads your screen, and only goes online to check for updates and verify a Pro license
What's next
- A Windows version (people keep asking)
- Per-app rules, so you can turn the paper off in apps where you don't want it
- More papers
If you have ideas, I'd honestly love to hear them.
Pricing
PS: I already made my first sale yesterday from my X launch post :)
This was the whole reason I built it, so it's simple:
- Free: Plain Paper, forever, with every feature. No account, no trial timer.
- Pro: all 7 papers for $5 once, on up to 3 Macs, with lifetime updates and a 14-day refund if it's not for you.
For launch, Pro is $3 until November 23.
And for dev.to readers: leave a comment below and I'll reply with a code for an even better deal.
Links
- Website and download: shoji.ink
- Me on X: @_asheeshh
It needs macOS 13 or later and works on both Apple silicon and Intel Macs.
This is my first app, so any feedback helps, good or bad. And if you also read too many PDFs late at night, give the free paper a try. Your eyes might thank you.
Top comments (0)