Historical Timeline Creator Architecture

Published on
Historical Timeline Creator Architecture

Earlier this year I launched a small web app I made: a Historical Timeline Creator.

Since launching it, I made one update to it so that users who pay for it can use AI to generate timelines. Here’s a demo of that in action.

Back when I launched, I noted that I might describe some of the tech I used to do it. So here’s a peek behind the scenes.

Architecture

Somehow I only recently came across Excalidraw. I used it to create a nice architecture diagram of the Historical Timeline Creator.

Block diagram of the Historical Timeline Creator

The intersecting red/blue boxes convey that there are two modes that the site operates in: for local dev and deployment to Cloudflare. Some components/tools are only used in one or the other and some are used in both.

Astro

The site is largely built with the Astro web framework. It’s used for local builds and the production build on Cloudflare. Production builds/releases happen when a new change is pushed to GitHub.

I also use Astro for this blog - I appreciate how so much of it is the plain HTML/CSS that I (mostly) remember, plus nice things like Tailwind CSS and TypeScript support. It makes for really snappy web sites.

Flutter

The timeline rendering is handled via Flutter. I had previously written that code for a mobile app and wanted to reuse it here. Flutter makes that possible, although there is a cost in terms of data that the browser must download. That makes the initial load of the Historical Timeline Creator a little slow for my liking, but I do like that I can use my existing code.

The rest of the app communicates with the Flutter code via a Dart/JavaScript bridge. That’s how regular browser UI (like the textarea and button elements) can impact what’s rendered on the timeline.

Flutter itself only factors in the local dev workflow - the code that is included in the app is just the JavaScript that it outputs.

Convex

For authentication, billing via Stripe and calling the Google Gemini API, I’m using the fantastic Convex backend-as-a-service. There are some quirks that come with using React-centric frameworks like Convex and Astro, but they’re not show stoppers.

Using Convex allows me to mostly write my site as static HTML/CSS/JavaScript and keep most state and transactional stuff on the backend where it belongs (and on a backend that I just get to use and don’t have to host).

Cloudflare

I’ve been really pleased with Cloudflare so far, for my meager needs. They have a generous free hosting tier and the GitHub deployment integration is really handy. For this project I also made use of their middleware in order to ensure that portions of the site aren’t served unless the user is authenticated and has signed up for the paid version.

Various and sundry

I use some shadcn/UI components for … UI, and the browser’s LocalStorage API for persisting timelines for signed in users.

That about covers it, in case you were curious!1

Footnotes

  1. Also for me when I forget how I did this and want to refresh myself. :P