RSSAmplifier

Blog

smoores.dev - Recent Posts

smoores.devRSS feed ↗19 posts

Latest posts

The Unreasonable Effectiveness of ProseMirror Model in Rich Text Transformation

About month a go I might have added a minimal implementation of ProseMirror Model in Storyteller’s alignment package. But I can explain! It’s not my fault! It’s just that ProseMirror’s data model is such a good fit for rich text. I couldn’t resist. I don’t have a problem, you have a problem.

Making React ProseMirror really, really fast

Since the dawn of time, React maintainers have claimed that React’s virtual DOM is fast enough for complex interactions as long as you memoized your components. Then someone tried to put an entire Harry Potter novel in React ProseMirror, and I had to find out if they were right.

Using React Transitions for low priority text editor updates

React ProseMirror can really be quite fast, but what happens if we need to render it multiple times? Let’s walk through how to use React’s Transition APIs to speed up perceived performance by ensuring that only the critical interactive elements are updated immediately following user input.

The Perfect Lighting

The lights were too bright, and they were too blue. They were destroying our circadian rhythms. But we didn’t just want to get dimmer, warmer lights — we still wanted bright lights during the day. We needed adjustable lights. And if we wanted the lights to change color on their own, then maybe we even needed smart lights?

Announcing: Storyteller v2!

At long last, Storyteller v2 has arrived!

Serving Video with HTTP Range Requests

A deep dive into how HTTP range requests work, and how browsers use them to implement video streaming and pausable downloads.

“I don’t see how we can save it”

I’m being dramatic. I know I am. I’m certain of it. It’s just a tree.

There’s no such thing as an isomorphic layout effect

There’s something off about the most popular approach to quieting React’s warnings about using layout effects during server-side rendering. Let’s break down why the warning exists, and when it really makes sense to disable it without actually addressing it.

Why I rebuilt ProseMirror’s renderer in React

For the past year and a half, I’ve been re-writing the renderer for ProseMirror, the popular rich text editing library. This new renderer has finally been marked as stable and published as part of @handlewithcare/react-prosemirror, a library that integrates React and ProseMirror. Here’s a very deep dive into the journey I took, and why it led me where it did!

“Someone must have figured this out…”

Learning to make wind chimes is, it turns out, sort of like learning to make almost everything else.

Storyteller is on PikaPods!

PikaPods is a paid service for hosting open source apps like Storyteller. You can decide what resources are necessary to meet your needs, scale your pods up or down as needed, and deploy new apps with the click of a button. And now you can use PikaPods to easily spin up your own Storyteller instance!

Announcing: @smoores/epub

I'm going to start publishing individual packages that make up Storyteller's basic functionality, so that they can be used by other projects. I'm kicking things off with @smoores/epub, and hopefully filling a real gap in the open source space.

What is smoores.dev?

Recently, as I decided to reinvest in the contents of my personal blog, I also decided to rebuild it. Previously, it had been built as a very simple Flask app, with posts written in Jinja-templated HTML, and relied on the PyPI package Frozen-Flask to export the contents to static assets for deployment. This setup always required a bit more effort than I liked, but I really enjoyed the freedom that…

Overcoming I/O Limits in Node.js

Node.js has a (poorly) documented 2GB size limitation on file reads, and a seemingly undocumented 2GB size limitation on FormData parsing from web Request objects. This is a brief walkthrough of how I updated Storyteller to work around these limitations, allowing users to process longer books!

Phonetic Matching

Recently, I’ve spent quite a lot of time working on Storyteller. It’s an open source, self-hostable platform for automatically syncing audiobooks and ebooks. You give Storyteller the ebook and audiobook files for the same book, and it spits out a new ebook file with the audio embedded, such that the text can be highlighted while the audio is playing. In order to do this, Storyteller has to answer…

Back to Basics

The Oak Team, the engineering team responsible for building and maintaining The New York Times' collaborative rich text editor, just had the most engaging, fulfilling sprint that I've experienced since I joined the team in 2019. We collaborated, supported each other, and learned new things. And we didn't push a single commit. Instead, every engineer on the team spent two weeks learning about how…

ESNI: Making the Internet Private by Default

The internet as a system is inherently public. The primary protocols, like HTTP for website traffic and SMTP for email traffic, are plaintext protocols, and the underlying Internet Protocol (IP) includes fairly stable addresses (IP addresses) in every request, which means that the computers that serve content, like web servers and DNS servers, are constantly being informed about who, specifically,…

Dockerizing Legacy Scoop for Reproducible Development Environments

That title is a bit of a mouthful, huh? Probably a good idea to start with some context. "Scoop" is the name of the CMS at the New York Times, which is actually made up of a number of separate frontend apps that sit atop a shared backend. Most of the time I work on Oak, the collaborative rich text editor that the newsroom uses for writing news and opinion stories. Oak actually has its own…

SMTP: A Conversation

One crucial piece of network administration has always evaded me. Past the routers, VPNs, websites and Docker images, always just out reach, sits the big one: email. I have never been able to wrap my head around even the simplest pieces of email networking. Somehow, this fundamental part of the modern internet has always just been a little bit too complex, just a little bit too finicky.