Fighting for Component Independence
A tale of React, open source, and the quest for UI singularity
A codependent component is a sad component. Only by treating all components as first-class citizens can we scale UI development to great lengths. Are you with me? Good. You’ll get a cookie if you stick till the end.
React Cosmos started in 2014, in an effort to solve issues encountered in previous years while working on a beautifully out of control single-page app. The end goal wasn’t clear, but I was committed to turning my experience into something of value. After composing messianic READMEs, I fortunately stumbled upon React and immediately transformed the abstract project into something with React.
The team of six I was part of went on to built a large React codebase for the ensuing years and the Cosmos project slowly morphed into a development tool that enforced & enhanced the React model. In short, its function became to turn our source code into a dashboard for loading and testing each component in isolation, under pre-defined states ranging from defaults to edge-cases. You can tell we had a knack for graphic design.
The benefits started rolling in and the Cosmos UI became our dev homepage. Focusing your work on one component at a time beats rendering the entire app only to see updates on the part you’re performing surgery on. Stubbing all inputs (including server requests) also leads to thoughtful component design. Hot reloading further improved the feedback loop (props to Dan for taking interest in small projects).
Once this setup was in place, it unlocked additional opportunities. One was to reuse the data fixtures to double as unit test scenarios. The other was to take advantage of the unique URL each component-fixture combination had and to build a visual regression test suite on top of that.
You can also get the essence of Cosmos in the 5 minutes I struggle to be OK with speaking in front of hundreds at ReactEurope 15.
Fast forward to this year and the space for React playgrounds flourished with new ambitious projects. React Storybook and Carte Blanche are the ones I’ve heard of, and both offer unique perspectives. Cosmos continued to serve its purpose for my ex colleagues and generate modest Github engagement, but I started to suspect the newer generation superseded it.
Not so fast.
Then Bogdan Stefan started bringing serious contributions and sparked my interest in the project once more. Before investing more time, though, it was important for me to reiterate the mission and check the degree to which it’s already fulfilled by the other tools.
After some examination, I’m a fan of Storybook’s friendly “stories” and Nik Graf’s idea to generate random props, yet I find React Cosmos unique in its quest to surface the relation between raw input data and rich component output. The gif I posted a while ago conveys this idea well.
This idea of pulling out raw data from the app’s state and being able to fiddle with it and observe correlation is what drove this project from the very start, when debugging sessions amidst widgets, templates and models were so intense that getting to the bottom of a visual glitch required matrix-like immersion, and a great many mental resources at that.
Redux is a stepping stone in this area. Among other benefits, it says “your logic is over here and your state is over there”, which is a boon for DX. One potential downside, however, is the tendency to focus on the app level (since the state is global) instead of the component level, which in my experience is vital when building a large app employing many UI engineers.
This doesn’t mean Redux and React Cosmos are incompatible, they actually play along well. In fact, making them work together has been a longtime request and I recently joined forces with Bogdan to do just that. We’ve converted the local component state version and you can now play with the Redux version of Flatris. Notice the two-way binding.
The Redux integration is part of the 1.0 release, most notable for:
- New Proxy API, opening the door to Redux but also any other external state sources or visual augmentation plugins.
- New CLI, aiding user integration (because wiring JS projects creates enough headaches already).
Complex user interfaces are growing in numbers, and so is the use of React to support them. I think the future of React Cosmos depends on how easy to integrate it becomes. Community involvement is also key, as my ability to fulfil the project’s goals is inversely proportional to its growing parts. Furthermore, here are two areas I feel excited about exploring:
- The Atom plugin you see above is a working prototype that renders your components next to your code. Picture hot reloading with the component source, data fixture and live rendered instance in the same screen — the Holy Trinity of UI development. I recommend checking it out for yourself.
- Creating fixtures is by far the biggest pain. Not so much when getting started, but adding fixtures retroactively to a large existing codebase is a serious investment. The use of Faker to generate fixtures in Carte Blanche is a leap in the right direction, and an abandoned idea I’d like to see picked up inside React Cosmos as well.
If you want to join the fight, the contributing gates are open.
Here’s the cookie I promised — an early React experiment retrieved from the annals of Git. It’s a proof of concept meant to illustrate the idea that there’s no difference between low-level and high-level components (aka “controllers”). I tapped into the TMDb API and performed some CSS wizardry to create the sensation of a user interface without hierarchical edges.
Check it out live. Make sure to go back & forth using the browser nav buttons
What does your UI utopia look like? I’d love to hear your story as well.
… and remember,
Big or small, every component has the right to independence. Don’t make your components prisoners of complexity. Set them free!
As of 2018 I’m dedicating all my time to making Cosmos an awesome open source tool for developing React apps. If your team is looking to level up and add a solid testing foundation to your dev practices, get in touch at ovidiu.ch.