Yesterday I converted the last remaining folder in our source code to TypeScript strict mode. This feels like a good time to pause and reflect on the current state of the web codebase, and also list things that are still left to do.
Ed: This was an internal note I wrote for other people involved with Ente. But then, I thought, hey why not also publish it, some people might be curious about is going on inside the kitchen.
Overall, there are no more "global" refactorings left to do. Code from one place looks and works similar to code from other parts of the codebase, so everything feels as part of coherent whole, and code can be easily shuffled around. Dependencies are up to date. Hacks are minor and documented.
I can now get hit by a bus peacefully.
First, let me give a brief overview of how things stand.
All code is type-checked using the same TypeScript settings which enable strict mode, and a few more even stricter options.
All code is linted using the same ESLint settings, which are at their most pedantic, with only a handful of carefully considered opt-outs.
All code is formatted using the same Prettier settings, which are at their default (the main thing we customize is the indent width).
The upside of this is that if you're comfortable with TypeScript, then adding or changing code is a pleasure. The tooling will tell you if you're trying to fit a round peg in a square hole.
The downside is that since the settings are at their strictest / pedantic, people not familiar with TypeScript idioms might find it hard to understand what the errors are all about and struggle with making changes.
All dependencies are documented in
web/docs/dependencies.md
anddesktop/docs/dependencies.md
. The purpose of this is twofold - to verify that each of them is necessary (by needing to justify each one's presence), and to act as a psychological barrier in introducing new ones.Almost all dependencies are at their latest. The couple of exceptions are listed in the "Pinned" section of the doc.
Developer tooling is all standard. Install Node and yarn v1, that's it.
There is one major pain point around dependencies - desktop app distribution. More on that, and the other pinned dependencies, later.
- All code has been written by humans.
I know this for sure because almost all code has either been written before LLMs were a thing, or it has been written by me.
There was a small gap in the middle, when LLMs were coming out and I wasn't monitoring for humanity, but all contributions from that time have been rewritten (for unrelated reasons) by now.
The only exception I can think of is ImageEditor.tsx
whose provenance I don't
know about. Either ways, that file too is due for a rewrite, or at least a major
revisit, because of various type and lint issues. More on such files below.
Now let me get into the things that are still left to do.
While there are no directory wide TypeScript / ESLint overrides, there are many line or file level error suppressions. However, while their count is high (~hundreds), viewing/fixing them individually is inappropriate.
Instead, what's going on is that there are certain files (~tens) that need to be revisited or rewritten.
Revisited – This is the bulk of such files, which just need some touchups and minor refactoring. e.g.
FileList.tsx
,UploadProgress.tsx
. Simply converting the code to the idiomatic TypeScript that the rest of the codebase uses will also resolve the lint etc issues as a side effect.Rewrites – A few files, but two in particular, need to be dealt with separately -
export.ts
andwatch.ts
- because it would be a good chance to see if the features themselves need to be reworked. For example, should folder watch evolve into a two-way sync?, in which case we should rewritewatch.ts
, or if two-way sync is going to be a separate feature, in which case we can just fix the type and lint issues in that file.
These files are intentionally segregated in the apps/photos directory, and there are not that many of them (all of them are marked with a "TODO: Audit this file" at the top).
For the revisit case, each file can be dealt with separately in what should be a day or so's work. The rewrite cases are more involved (but we can also pick them independently, and at convenience; they don't block the other changes).
It is important to re-emphasize that there is nothing "broken" in these files, on the contrary they are among the most solid of the code in the app since they've been around the longest. They just need a bit of loving, and in the rewrite cases, a think through of the functionality itself in light of the new feature requests that users have come up with since they were initially written.
So files were one thing. In terms of code structuring, we need to split the photos and public albums app. This should take a week or so.
Once both these things - the ~10 TODO files in the revisit category, and splitting the albums app - are done, then "packages/new" (a temporarily holding place to aid the segregation) will not be needed.
That point in time would've been an even nicer point to write this note, but sometimes we make do with the chances we get to want to speak.
In any case, we can draw a metaphorical line there, because after that will be left a laundry list of chores, mostly independent of each other and with no specific urgency or timelines attached:
The login flow should be refactored into a single page. Right now the flow is spread out over a dozen pages, which (a) makes the logic hard to follow, and (b) makes in unnecessarily onerous to add new apps. If the entire login flow was a single page, then creating a new app that uses the existing Ente account will become pleasantly trivial.
ESM migration for dependencies. At some point, we'll need to start using ESM in our app. I have nothing against doing it right now, except many of our dependencies (e.g. libsodium) don't support ESM.
Releasing a new desktop version has gone from a moment of happy excitement to something I dread. As a fresh example, we recently updated Electron builder to fix a bug in the Windows app signing, but that brought with it a new bug where the auto updater uninstalls the app for some Windows users (even worse - fixing it won't fix the issue from the user's perspective in one build, because the updater itself is coming from the old buggy build). This is just one example, there are other non-code related issues with app distribution, and I don't really have a "solution" - as such, this is more of a FYI / rant.
Dependencies are pinned either because the newer versions of the library are ESM-only, or pinned to avoid bugs in newer versions. However, one of the pins, a hash library used by auth web, is because of breaking changes in the new version that requires (minor) code changes on our part.
Move the families app codebase from a separate repo to live under the web/ umbrella.
Consider moving from Next.js to Vite.
As a summary,
The web code is in a healthy state.
Two items – revisiting ~10 files, and splitting photos/albums – are the main remaining blemishes.
Then there is a rewrite of a couple of files, and a longer laundry list of chores, which can be picked independently if we get time.