For the first few months Algebra worked the way most simple websites do. The browser asked the server for a page, and the server, written in Flask (a popular tool for building websites), took a ready-made page skeleton, a template, filled it with data from the database and sent the whole thing back. For pages that never change and for a booking form, that was more than enough.
Over the winter, though, Algebra stopped being a website with a calendar. A student panel arrived with tasks in which formulas have to look the way they do in a textbook, along with a formula sheet, a level check, the first games and a lesson room with video and a whiteboard. All of this happens on the student's screen: it reacts to clicks, recalculates and changes without the page reloading. With the old approach, that meant more and more separate bits of code stuck onto the pages, each knowing less and less about the others.
Why build it again
In January I was still trying to rescue the old setup. From the largest pages, the task panel and the formula sheet, I pulled out the look and the behaviour into separate files, just so they could be read at all. It helped for a while, but with every new feature the same trouble came back: how a single page worked was scattered across several files in different places, so a fix in one place broke something in another.
React, a tool for building websites that behave like apps, solves exactly this problem. It splits the screen into building blocks, and each of them, a task window for example, keeps its look and behaviour in one place. TypeScript adds a precise description of the data that travels between parts of the application. It sounds like a formality, but in practice the computer catches a good share of errors before a new version reaches the site, not for a student who happens to be trying to book a lesson.
A faithful copy first, changes later
When you rebuild something that works, it is tempting to fix everything at once while you are at it. I decided that was a straight road to a situation where nothing works and nobody knows why. So at the end of February I moved the pages over one by one, each so that it looked and worked exactly as before. The ones the platform cannot exist without went first: tasks, Google sign-in, bookings and messages. Then the calendar, the profile, the level check, payments and the lesson room, and finally ten smaller pages that until then had existed in name only.
Only when the new version did everything the old one did did I start making changes. At the beginning of March the server stopped assembling pages, and since then it only stores data and answers the questions the website asks it, while what the user sees is put together in their own browser. I removed the old templates from the project, and the two parts began to live completely separately.
The website and the data in two places
Separating the two parts also changed where everything runs. The part the user looks at is now a set of ready-made files sent out by Cloudflare, a company that keeps copies of websites close to their visitors, so there is no server for me to look after there. The data part stayed with Render, a company that runs applications on its own servers, and in April I moved it to a similar service, Koyeb. The database itself moved in March from Neon to Supabase, where it still runs today.
This split brought problems I had known nothing about before. The browser looks after security and does not let a page from one address talk freely to a server at another, so the data server had to be given a list of addresses that are allowed to ask it things. The sneakiest one turned out to be a small detail: the server redirected questions sent to an address without a slash at the end to the same address with one, and on such a redirect the browser rejected the question before it even got there.
A lesson room that changed every few days
Alongside the rebuild, I was looking for a way to teach online without jumping between apps. At the end of January I put a Miro whiteboard on the site. At the beginning of February I replaced it with the tldraw whiteboard plus video calls through Jitsi, and a day later with the WBO whiteboard, because tldraw had switched off the rooms I was using. Two days after that it turned out that the public Jitsi server cuts off calls placed on someone else's site after five minutes. So that same day I tried JaaS, Jitsi offered as a ready-made service, and in the evening I switched to my own video connection built on PeerJS, a tool that connects browsers directly to each other.
Each of these changes fixed something and took something away. I took one thing away from those weeks: someone else's service placed on your own site always plays by someone else's rules, and those can change overnight.
After the switch
Today everything the student sees is built with React and TypeScript, and the Flask server deals with nothing but the data. A new feature usually means a new building block on the screen and a new question the server knows how to answer, not another bit of code stuck onto an old page. The most important lesson from this switch is not about React, though: when rebuilding something that works, it is worth recreating it one to one first, and only then improving it.
The whole series
This is the third part of a series about how Algebra i Spółka came to be:
- The first Algebra: Flask, templates and the PHP I quickly gave up on
- Bookings that disappeared with every deployment
- Algebra from scratch: from Flask templates to React and TypeScript
- A price list in a file, Premium and my first payment gateway
- Tasks, a formula sheet and drawings that would not add up
I describe what the whole thing looks like today in the post Algebra i Spółka from the inside.

