Over the past two weeks, we have been working hard on migrating parts of Medusa's codebase to TypeScript. We are doing this for a couple of reasons all of which have to do with improving the developer experience. Now that we are slowly merging the first parts of this migration we would love to share some insights into why we didn't just go with TypeScript in the first place and why we have decided that the time was right now.
A bit of background
Before working full-time on Medusa we did agency work for a handful of different e-commerce clients; one of them wanted to migrate away from their solution back then and when we couldn't find a new suitable platform for them we agreed to build a custom solution from scratch. We didn't intend for this to be anything other than a solution that would optimize and automate all the workflows for the client so we went straight into development mode. As the project grew and our client grew, new requirements emerged and we had to go back to the drawing board. This was the first time that we had to weigh our options in the context of the project being maintainable and easy to use in the long term. We evaluated approaches based on a couple of insights:
- Growing businesses change (a lot)
- When you are on a growth path you can get by with basic tools in the beginning, but when processes get more complex you will typically need to adapt the tools in your stack. We wanted to build our architecture to accommodate this insight; making it easy to compose your e-commerce stack with the best-in-breed tools. Note*:** best-in-breed for a small 2 person team is not the same as best-in-breed for a 25 person team, so your stack has to be dynamic.*
- Growing businesses need control
- If you are growing rapidly you need to be in control of what happens when; you can't make a feature request and then sit around for 2 years waiting for it to be made available. You must be able to get the process moving straight away.
- Customer Experience is king
- If you are trying to stand out in the crowd of standardized websites you need to have a razor-sharp focus on the customer experience. Customers should feel that they are entering into an on-brand universe when visiting an e-commerce site and to do so you may have to change up the standard browsing, purchasing, and checkout process to truly accommodate the product or brand.
- Developers are the key to making all of the above succeed
- Developers get a bad rap for being expensive, slow, and complicated to work with and this makes sense to a certain extent; however, there is an incredible amount of projects - Medusa being one of them - being built that focus on making developers more efficient, making the requirements for developer capabilities lower and ultimately making it easier for merchants to start leveraging headless technologies earlier than they otherwise would have. As the ecosystem of great developer tools grow it will become increasingly appealing to new merchants to make the switch as early as possible.
The above requirements were foundational for some of the high-level decisions we took in the early days:
- We created a simple and modular architecture that gives you all the basics out of the box and provides the interfaces necessary to easily integrate with other tools to give you the optimal stack.
- We open-sourced everything to give users and merchants full control of what gets built
- We provide a great APIs and tooling to create custom e-commerce experiences that move the needle
- We think carefully about how to design things in the most developer-friendly way and choose tools in our stack that developers like.
Why we didn't go with TypeScript in the first place
You may be thinking now: okay but why on earth didn't you start with TypeScript if you wanted to use tools that developers like. The truth is that when we started developing we were optimizing for speed; with limited TypeScript experience back then we felt that there would potentially be many unknown issues to overcome if we had decided to go down that route. Furthermore, TypeScript was not as widely established as it is today and it would have been really sad if we had chosen a language that would wane in popularity after a couple of years (cough CoffeeScript and friends). That isn't to say that we didn't like TypeScript, on the contrary, we have always thought TypeScript was incredibly powerful, however, by Lindy, we decided that it was worth waiting a bit.
Not going with TypeScript in the first place allowed us to do other amazing things like creating an incredibly powerful core architecture and a handful of great plugins that provided integrations for systems like Stripe, Segment, Sendgrid, and others. We were able to do this at an incredible pace and iterate quickly, changing APIs on a day to day basis (one of the privileges of the early days with few customers) without too many complications which eventually got us to this point in time, where we have figured out the ins-and-outs of how data should be flowing and where we have a good understanding of the types and interfaces needed for modularity and composability.
Why is the time right now
When you are the lone developer and user of a project you know the APIs intimately because you have written them. Sometimes your memory might be a bit unclear, but generally, it is not a distractor for your workflow, so you don't think that much about IntelliSense not kicking in. That changes a lot, however, when you start working on things that are not your creation and not only from the user perspective also from the contributor perspective. Say you are working on code that calls some function that someone else from your team wrote. While you might have been in talks with your teammate about how the APIs are meant to work and what kind of dataflows should be going on, you might not know the exact implementation details, and that is when it starts being super useful to have all of your tooling in place.
We are so happy to see the community around Medusa growing and we are therefore very much aware that we need to improve all the tools in the ecosystem as much as possible to allow for the best developer experience. Furthermore, we feel confident that TypeScript will be around for a long time, and for this reason, now is the time!
How we are going about it
Migrating our entire codebase will take some time so we are starting with the parts that make the most sense and moving along. We are already using TypeORM for the data layer so all of our database entities are typed. We have gone ahead and added TypeScript to all of the core API's controllers typing all payloads and responses. This adds the amazing benefit of being able to share the type definitions between the core project and our JS client essentially ensuring that when you are making calls through our client library you are seeing the exact class properties that are being used to validate the request payload.
We are going to add TypeScript throughout the core package as we go along and our goal is to migrate all of our code eventually. If you are interested in helping out or want to try Medusa go check out our GitHub repo and join our Discord where you can get direct access to the engineering team!