In this post, I would like to share my experience by working on personal media library so-called "headlessmedia". It is the set of media libraries designed for UI frameworks such as React and Vue to help ease the work when it comes to media development experience. Stay tuned and read on bros 😎
In my previous post, I wrote about how I could use 1 KB of XState to optimize next-media package at Axon but decided not to due to maintainability. Later, I figured out the way which could satisfy my concerns about next-media. I could get minimal bundle size addition, performance optimization and zero new concept for maintenance. Let's travel back in time and see I have done that step by step 🚶🏻♂️
Interestingly at first, I came across this tweet from Evan You - creator of Vue.js. This got me exciting to try out how @vue/reactivity could work together in harmony with my next-media. As it turns out, it's super easy to switch from XState to @vue/reactivity package and it's pretty small - less than 4KB at max will be added to the bundle size. We only need to change two places to make the switch happens beautifully. We need to use reactive system from @vue/reactivity to store media state as below
And then useMediaContext, we can drop useEffect in favor of effect from @vue/reactivity
And we are done switching from @xstate/fsm to @vue/reactivity. It's too easy to be true in my standpoint 😅. This got me thinking about one question "Are they sharing similar trait under the hood, that's why it's so easy to swap them!". In order to answer this question, I decided to spend some times to study them.
Having fair amount of knowledge from both sides, I could conclude that they share one key important trait to help me overcome limitation of React's performance. It's Observer Pattern. I decided to wire up a fairly simple but effective observer pattern implementation to provide exactly what I achieved previously (you could visit my post on observer pattern here but with implementation in Golang).
And here is the implementation of useMediaContext
And that's it. It's that simple to overcome limitation of React's performance. I now got the following as I desire
Up until this point, everything is going well for next-media. But, I found something I would definitely love to do. I came across one of Adam Wathan's repo called headlessui. It absolutely took my breath away about how one libraries could truly be reusable by being headless. And, I decided to make one for media and call it headlessmedia. By being a core maintainer of media experience at Axon, I have fortunately faced a ton of problems that not many places could offer me. But there is always room for improvement, and this repo is exactly where I want to go. It's 100% out of my comfort zone and I feel like it's something I love to do. There are several things that I found more or less limited (for various reasons) about media experience at Axon. Here are the things I found crucial:
Most of our application of media at Axon only requires to serve single media element at a time. Our next-media package support that cases very well. But there will be limitation in development experience if we have to handle more than media at the time to control because most control items should be rendered inside its according context. We can overcome that by attach different ids to native media elements and take control from their instead but that approach is not very intuitive in React at all and very imperative. Headlessmedia package is not having this problem since I decided to hoist all the states up to one singleton pub/sub store - aka channels. Any media elements and their related controls can interact with each other as long as they can grab the ids of their target media element. From my personal standpoint, it's an enhancement over simple observer pattern but work with multiple instances of media players in the screen regardless of its location
Headlessmedia's mission is the followings:
At of now, I'm actively working on releasing v1 of the packages. It's super exciting to see how much code I could share among all libraries implementation. I decided not go deeply into every design I have made for headlessmedia in this posts and hold it for later posts once I release them. If you happens to read this post before I release it (hopefully - I don't get paid for doing OSS so that my time for it is very limited), please feel free to check out the repo and make contribution if the idea fancies your ticket ^^
All in all, I'm really glad that I could make a progress over my past self. Previously, I had to implement different state management in Vue, Angular and React (Dependency Injection, Context and RxJS accordingly). And now, not only could I deliver a fairly simple yet minimal and complete framework agnostic solution with software design pattern applied but also entering myself into a horizon of challenges that definitely helps me later on in my future work. Good bye for now and until next time guys 🤘
❤️ ❤️ ❤️ Be well Be happy ❤️ ❤️ ❤️