Hive, a Classroom Curation Platform
A classroom platform for publishing collections of links, images, and video, migrated from JSX to TypeScript during weekly releases.
The source code is client-owned and is not public.
What it is
A classroom content-curation platform: curators sign in, pull items into collections, tag and order them, and publish the result to a public-facing view. React front end, AdonisJS API, PostgreSQL underneath, deployed and used in production.
The application was already live when I began the TypeScript migration. New features still had to ship while I converted the existing modules.
TypeScript migration
The starting point was a JSX codebase with no type coverage and an active feature roadmap. The approach:
- Enable
allowJswithcheckJs: falseso JavaScript and TypeScript modules can coexist. - Convert utility modules first, keeping each change small enough to review and deploy.
- Define
Item,Collection,Tag, andCuratorbefore converting the components that use them. - Keep strict settings enabled on converted modules.
The migration exposed API fields that could be null but were rendered unconditionally by the UI. I added checks at those call sites.
Rendering and query latency
Feedback often described the symptom without identifying the cause. “The list feels slow” meant a rendering problem on one screen and a query problem on another. I had to reproduce each report before deciding where to fix it.
I also left instrumentation too late. Without request-latency measurements, performance conversations were harder to resolve. I would add that visibility earlier on the next project.
Design decisions
Incremental TypeScript migration, file-by-file, with `allowJs` on
RejectedA big-bang rewrite on a long-lived branch
Weekly releases continued during the migration. With `allowJs: true`, typed and untyped modules could coexist, so I could deploy each converted module and pause the migration when feature work took priority.
AdonisJS over a bare Express setup
RejectedExpress with hand-assembled middleware, validation, and ORM
Adonis provided validation, migrations, and an ORM within one framework. That reduced integration work for a solo developer on a client deadline, at the cost of a smaller ecosystem than Express.
PostgreSQL with explicit migrations from day one
RejectedA document store, or an ORM with auto-syncing schema
Items, collections, tags, and curators form a relational model. Foreign keys enforce those relationships, and explicit migrations give schema changes a reviewable history.
What I’d do differently
- Turn on `strict` mode at the very start with the whole codebase in `allowJs`, rather than enabling strictness per-module. Ratcheting strictness later meant revisiting files I had already converted once.
- Write the seed script in week one. I tested against hand-made data far longer than I should have, which hid at least one ordering bug that only appeared with realistic volume.
- Instrument earlier. I had no request-latency visibility until late, so performance conversations with the client were qualitative when they should have been numeric.