Thanks @mrstegeman,
We discussed migrating the WebThings Gateway codebase to TypeScript a few years ago and at the time we decided against it for various reasons, but the balance of tradeoffs may have changed over time and as the code base has grown, so I think it’s worth revisiting now.
Here are some obvious pros and cons of a move to TypeScript I can think of…
Pros
- The type safety of TypeScript means more bugs will be caught at compile time rather than run time, making the gateway’s code more reliable
Cons
- There are fewer TypeScript developers than JavaScript developers, which may make growing the number of contributors harder
- TypeScript adds an additional compile step to our build process, which could harm developer productivity
Maybe some people with actual experience with TypeScript can comment on or add to these pros and cons?
Reliability
Making the gateway more reliable really appeals to me as one of my main goals for the gateway this year is to make it more production ready (e.g. by considering replacing Raspberry Pi OS with a more production quality base OS with better security and automatic software updates).
Arguably other ways to improve the reliability of the code are to increase the test coverage of unit tests and integration tests, but there will always be some bugs that slip through the net which could have been caught by static typing.
I do have a number of reservations though…
Barriers to Contribution
The first reason is simply that I haven’t learnt how to use TypeScript myself yet, which on its own is not a good reason for an architectural decision, but there are some real practical considerations to think about. Currently there are only three people who can review core gateway code: @mrstegeman, Tim Hellhake and me. If I can’t review that code then if one us writes code there’s only one person who can review it, which could slow down development.
The obvious solution to that is for me to learn TypeScript, which I’d like to do, but I’m conscious I may also need to learn Rust (to hack on the registration server) and get deeper into Android development (to work on a mobile app) this year, and it’s very unlikely I’m going to have time to do all of that extra learning whilst also starting a business.
The other (more scalable) solution to that problem is to get more contributors experienced with working on the core gateway code so that we can assign more peers, but that process is going to take time. Moving TypeScript also arguably makes that harder simply because there are fewer TypeScript developers than JavaScript developers.
Increased Build Times
The second reservation I have is about the increase in build times and its effect on developer productivity. Since webpack and TypeScript were introduced to the codebase our install and build times have increased by an order of magnitude.
This was particularly noticeable to me when developing the transition UI for 1.0, when a one line CSS change would require an extremely long wait for a re-build to test. We can work around that for front end development to a certain extent by using browser developer tools to write code before copying it across to an editor, but that doesn’t help back end development and it’s still a very painful development cycle.
When the project first started we had live reloads of static resources on the front end and plain interpreted Node.js on the back end so the development cycle was extremely fast. The introduction of webpack as a build step eventually put an end to the live reload, which I wasn’t very happy about at the time, but I couldn’t argue with the end user performance benefits. TypeScript seems to have made the situation even worse.
Is there a way we can provide a better developer experience without compromising on the user experience?
Obsolescence
My third reservation is that I would like to build WebThings Gateway to last, ideally for decades. I have a hypothesis that TypeScript is not going to have a particularly long lifespan and will eventually be made obsolete by a future version of ECMAScript (JavaScript). This is because TypeScript exists to address what some people perceive as shortcomings of JavaScript, but over time such features tend to get integrated into the ECMAScript standard. So will TypeScript still exist in ten years time? How would we feel about converting the codebase into TypeScript, only to convert it back to JavaScript at a future point in time once it has grown even bigger?
I would argue that keeping the code base as vanilla as possible and reducing the number of dependencies helps to make it more future proof. There’s clearly a balance to be reached.
What other pros and cons are there for the move to TypeScript that I’m not aware of? These issues are far from being unique to the WebThings project, so what experiences do people have from other projects which could be relevant here?
I can think of a few options going forward:
-
Revert the whole code base back to JavaScript but increase test coverage to improve reliability
-
Convert the whole code base to TypeScript but find a way to improve build times and developer productivity
-
Convert the back end to TypeScript, but leave the front end as plain JavaScript
-
Convert the whole back end to Rust instead
My instinct is option 1, but mainly because I am suspicious of TypeScript and I don’t like change Rationally, I know there are significant benefits of TypeScript which means we should give it serious consideration. Also, no amount of automated testing is ever going to catch all the bugs that static typing could, and vice-versa.
The wildcard option 4 brings all the benefits of static typing, and much more, but would be a very significant effort we probably don’t have the resources to pull off at this point. (It’s probably more realistic and helpful to convert some adapter add-ons to Rust first, rather than the core gateway application.)
I feel uncomfortable about option 2 for all the above reasons, but option 3 feels like it could be a reasonable compromise, if we can improve the developer experience. We could keep the front end as vanilla JavaScript to reduce build times and make it more future proof, but reap the benefits of TypeScript on the back end where it can have the most impact and where I think the future proofing argument is harder to make (given Node.js already diverges from the ECMAScript standard).
What does everyone think?
P.S. This might be a good topic to discuss at the first monthly public WebThings meeting, which we’re hoping to organise soon!