Hi, it’s 2024 and in non-breaking news - React is quite popular. Just to be clear, this is not going to be a click-baiting, ‘stop using React right now’ type post. I love React. As a front end developer with a passion for building reusable components, developing in React has been a beautiful experience for me so far.
However, developers seem to have arrived at the point where React is the default option for any project that walks in the door, disregarding the unique context and problem space each one presents.
I found myself reflecting on this fact when the time finally came to embark on a redesign of our own website.
At MadeCurious, our guiding North Star has always been to ‘build the right thing’. This means prioritising thoughtful tool selection to ensure we’re solving the problem at hand (rather than reaching for the newest, shiniest toy every time). It made perfect sense to approach our own website the same way we usually do - by selecting the right tools to solve the problem.
For me, this resulted in a deep dive into whether React was the best tool for the job.
And if not, what was?
Planning the front end architecture for our Silverstripe site
While building our own website was a similar shaped problem to some of our other projects, it also presented some unique challenges. We needed to create a digital front door that was welcoming and accessible to anybody curious enough to knock on it.
To effectively communicate who we are and what we do, we needed to create a great experience that allowed users to focus on the content and navigate to the information that interested them in a frictionless manner.
Throwing in the odd bit of fun or ‘pop’ here and there to reflect our culture seemed like a good idea too.
The other side of the equation was ensuring we keep an eye on scope and consider the amount of effort required with any approach when weighing up how to best solve the problem. As with our partners’ websites, we wanted to ensure any effort invested translated into substantial value. Looking forwards, we also want our solution to be easy for people to update, maintain, and adapt.
With all that in mind, I made a list of key considerations when planning our approach for the front end:
- Accessibility
- Performance
- Usability
- SEO
- Maintainability
With Silverstripe being our CMS of choice at MadeCurious, we decided to reassess the options for crafting a front end that would help prioritise the areas outlined above.
Potential JavaScript approaches for Silverstripe
Is React worth it?
With its aforementioned ‘default option’ status, it made sense for React to be the first stop on our tour of potential JavaScript approaches for a Silverstripe site (or any server-rendered, CMS-based site for that matter). We evaluated the pros and cons, and assessed the likely ROI when it came to value delivered if we ventured down the React path.
React - the pros
- Component-based architecture and virtual DOM lends itself well to reusability and creating a coherent and consistent user experience.
- Great developer tools.
- Excellent community and ecosystem of resources built up around the framework.
- Reactive properties make engineering interactive components and other UI features easier.
- In a similar vein - allows us to avoid DOM manipulation (à la jQuery days) when crafting complex interactive experiences.
React - the cons
- Silverstripe uses server-rendered templates by default, with headless features still in their infancy (and not well documented as of yet).
- Although we’ve used React extensively in other projects, we’d likely need to re-architect our approach here (and potentially pull in a meta framework like Gatsby, Next.js etc) for a Silverstripe back end.
- On top of architecture updates, we’d need to reassess our approach and potentially redevelop some resources in relation to SEO, performance and accessibility on Silverstripe sites.
- ‘Known unknowns’ - basically the risk involved with overhauling our approach to CMS sites and the effects that may have on scope, timeframes and costs.
It’s worth noting that when assessing a React approach for Silverstripe, we were assessing it as an entire solution for the front end. The option of adding ‘sprinkles of React’ in amongst our server-rendered templates was not covered and instead, kept in our back pocket as an alternative option to going all-in on React. More on that option later in this series.
React had a bunch of very attractive pros. On the flip side, it also had some rather troublesome cons when placed in our particular context.
The question I kept coming back to, however, was ‘what do we actually need React for on this website?’.
And with that, I set off in search of other options.
Other JavaScript frameworks and tools
Aside from flashbacks to my jQuery days, my focus on Single-page Application (SPA) frameworks in recent years left me scratching my head when it came to viable alternatives to React. This had me scouring all four corners of the internet to learn from people much smarter than myself.
Some of the approaches I investigated included:
- Alpine.js
- Hotwire
- HTMX
- Vue components
- jQuery (just kidding - it’s 2024 😉)
- Vanilla JavaScript*
*‘Vanilla JavaScript’ refers to using plain JavaScript without a framework, as the top result when Googling the term communicates in a rather obscure (but funny) way.
Some were not feasible at all.
Hotwire, for example, is a really interesting concept but not likely to play nicely with Silverstripe (and also just very different, conceptually, from any of our current stack).
Alpine.js looked like a promising, lightweight solution to shortcut some common behaviours but security concerns left me with doubts about its feasibility. Its reliance on inline directives and potentially needing to loosen our Content Security Policy (CSP) to use it were less than ideal. While the library seems to be gaining popularity, I wasn’t confident enough to go all in on it. Still, it’s on my watch list and I’m actively seeking out content to firm up my understanding of the pros and cons.
HTMX was in the same boat.
While Vue arguably seems to lend itself to implementing components in isolation slightly easier than React, we’d still need to get the data into the components (probably by configuring a GraphQL API within Silverstripe). We hadn’t ruled this out, but wanted to make sure that extra effort was warranted before starting down that path.
Finally, Vanilla JavaScript seemed to be sitting in the corner, quietly waving a ‘Use the platform!’ sign at me the whole time. I hear you Vanilla JavaScript. I’m picking up what you’re putting down.
Using the platform
I’m a big advocate for keeping things as simple as they can possibly be. I love clean solutions.
That being said, I think you always need to be looking ahead and factor any obvious challenges coming your way into your decisions for right now.
Frameworks and libraries exist for good reasons. They can significantly speed up development, provide solutions to common problems, and introduce beneficial patterns and practices. However, I really like using native capabilities when it makes sense to do so as it means we can tap into many benefits.
The benefits of taking a native approach
- Performance: Applications built with native web technologies tend to load faster and perform better because they don't carry the overhead of additional framework code. The browser can immediately parse and display your content without having to interpret a framework-specific way of rendering UI components.
- Simplicity and Maintainability: By using standard web technologies, your codebase can be more straightforward and easier to maintain. There's no need to understand the specific conventions, lifecycle hooks, or state management solutions of a particular framework, nor keep up with constantly evolving patterns.
- Fewer Dependencies: Relying less on third-party libraries and frameworks reduces the risk associated with dependencies, such as breaking changes in updates, security vulnerabilities, or the project becoming unmaintained. It also eliminates the need to manage complex build tools and transpilation steps required by some frameworks.
- Longevity: Web standards evolve slowly and with a focus on backward compatibility, meaning a site built today with standard web technologies is likely to work far into the future without requiring significant rewrites. On the other hand, JavaScript frameworks can have shorter lifecycles and may require substantial rewrites to accommodate major new versions.
- Lower Learning Curve: New team members only need to be familiar with standard web technologies rather than the intricacies of a specific framework. This can shorten onboarding time and make it easier to find developers with the necessary skills.
It turns out Vanilla JavaScript is also in a pretty awesome place.
Long gone are the days where you’d reach for jQuery to fill in the gaps when building an information-based website.
Reviewing our designs, I was confident we could leverage Vanilla JavaScript to:
- Solve our problem - which was to create an accessible digital front door which effectively communicates who we are and what we do.
- Add some pops of fun to provide a joyful experience which represents our awesome people and culture.
- Prioritise accessibility, performance, usability, SEO and maintainability (although I knew we’d need some guardrails to follow through on that last point).
Adding some guardrails to Vanilla JavaScript
I had two outstanding concerns when it came to running with a bread and butter solution of just pure HTML, CSS, and JavaScript.
1. The potential complications of developing our People page
The first was that the design for our people page meant development could get tricky when it came to managing the interactivity and state without a framework of some kind. Still, my concern wasn’t severe enough to prevent us progressing with a Vanilla JavaScript approach.
I was confident we could come up with a sensible solution when the time came to develop this feature. I also had the ‘sprinkles of React’ approach in my back pocket to investigate further if required.
2. The maintainability of code
The second concern was the maintainability of the code and how it would fare without the prescriptive structure of a framework to fall back on.
React itself is technically a library and as such, isn’t prescriptive about such things either. Fortunately, communally agreed upon best practice and meta frameworks have stepped in to ensure we have sensible defaults across all our projects.
It was important to me that we provided similar structure and guidelines around how we manage our Vanilla JavaScript so that it doesn’t descend into a fragile web of chaos over time.
We landed on the Module Pattern for architecting our custom JavaScript.
This allowed us to:
- Create reusable components
- Organise code effectively
- Manage separation of concerns better
- Avoid namespace conflicts
It also creates a smooth path forwards for adding new features in a sane way as the site grows and adapts over time.
Next steps: implementing our Vanilla JavaScript architecture
At this point, we’d settled on:
- A Silverstripe back end
- Plain old JavaScript (in lieu of a framework) for the front end
- The Module Pattern to organise and structure our JavaScript
- Pulling in a framework (like React or Vue) in isolation for more complex UI features if required
In the next post, I’ll dive into more technical detail regarding how we stitched this all together in reality and the challenges we hit along the way.