Typefully tech deep-dive

December 19, 2020

After sharing the numbers behind Typefully's launch, I thought it might be interesting to do a deep dive on the tech we used to develop the project.

It's as solid and boring as you would expect if you know me, with a bit of shiny new stuff on the frontend.

Backend

The backend runs on Django. Funnily enough, it's just an app within the Mailbrew's Django project. I did this to optimize costs since we are currently over-provisioned for the Mailbrew backend.

API logic is written with Django Rest Framework. All in all, we are talking about 700 lines of Python.

$ cloc typefully
      28 text files.
      28 unique files.
       4 files ignored.

github.com/AlDanial/cloc v 1.82  T=0.04 s (635.4 files/s, 21738.1 lines/s)
-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
Python                          28            217             41            700
-------------------------------------------------------------------------------
SUM:                            28            217             41            700

Our DB of choice is Postgres, with a Redis sprinkle for caching and key-value storage.

Async tasks are handled with Celery. For long threads (> 10 tweets), we run publishing asynchronously to avoid timeouts. We also have a task that periodically checks for scheduled threads and posts them on Twitter.

Frontend

It's a React app, bootstrapped with Create React App, that uses our proprietary Mailbrew UI Kit. Fab tried to match Twitter's aesthetic to make it feel natural to write tweets there.

We use SWR for making network requests and to cache the results. This is true for the drafts list on the left and for the draft you are currently editing.

When you edit, we update the local cache in real-time and lazily sync the edits to the backend by performing multiple (debounced) calls to a REST endpoint. There is no persistent connection to the backend and it works surprisingly well for single-player editing.

The thread preview on the right reads from the same SWR cache and splits the draft into tweets to compose a thread.

We wanted to provide a great lag-free editing experience, so it was essential to limit re-renders. To achieve this, we had to decouple components to avoid useless re-renders, especially for the main editor. Typing there should case as few re-renders as possible.

For this purpose, Recoil, the newest React state-management library, was pretty useful. It allowed us to share state between sibling components without needing to hoist that state to the parent component. Changing that shared state only updates consumers of that state. It's a quite useful tool to have in your at your disposal..


All in all, I think Typefully is our best work yet. I love how we get to raise the bar with each side project, both technically, strategically, and marketing-wise. I can't wait to build and ship our next thing.