Elder.js is a new meta framework based on Svelte. What does it bring to the table?
Svelte apps with 0kb client-side JS
Svelte introduced a radical new idea by becoming a compile-time framework, resulting in single page apps without a run-time framework. But while Svelte apps don’t have to load a framework script (like react.js
and vue.js
do), they do run as client-side JavaScript code.
Elder takes this a step further by turning Svelte apps into server-side generated HTML and CSS and 0kb client-side JavaScript. This is fantastic for performance and delivering small footprint web things. With this approach Elder sets itself apart from other meta frameworks like Next.js, Nuxt.js and Sapper which only add more JS to your apps on top of the frameworks they’re built on. The concept of SPA’s with zero JS by default is slowly gaining more traction. Next.js recently added an experimental “no run-time JS” feature and other frameworks like the Preact-based Microsite are popping up.
Progressive enhancement with partial hydration
0kb of JS is a great baseline. But eventually you’ll want to add client-side interaction and logic to your project. Elder’s solution to this is partial hydration. Which is a fancy way of saying only specific parts of the web page become interactive once client-side JS is executed. Elder has a declarative approach to partial hydration using attributes on dynamic page components for passing props and hydration options:
<!-- typical Elder.js page -->
<svelte:head>
<title>My web page</title>
</svelte:head>
<MyStaticComponent ssr-prop-a={ value } />
<MyDynamicComponent
hydrate-client={{
ssrPropA: value,
clientPropB: value2
}}
hydrate-options={{
loading: lazy,
preload: true
}}
/>
With this strategy, your app only includes client-side JS once you use hydration. And with the hydration options you decide when the JavaScript bundles are loaded and when hydration kicks in. This too is different from the isomorphic approach of the other meta frameworks. With isomorphic apps a server-rendered HTML page is served, which loads scripts in the browser and then re-renders and hydrates the entire page client-side. Hydration is a heavy operation taking place on the main thread and thereby blocking interaction. Elder completely avoids this issue using smart partial hydration.
On a personal note, I’m a long-time fan of progressive enhancement. Partial hydration fits right into this strategy where you start with a robust static web page and incrementally enhance it. Now we could deliver static web pages long before the invention of SPA frameworks and make them interactive with a dash of JS. What’s new about Elder is that you can now start with a fully static site and incrementally enhance it with client-side script using one and the same framework and programming language. To me, that’s a big step and I hope more frameworks adopt this approach in the future.
The adolescence of Elder.js
Thus far we’ve delivered a handful of projects using Elder. It lives up to its expectations of being a fast and lean framework. But as it’s still young, we also experience some quirks and limitations:
- Development mode can be quirky: we often find ourselves restarting the development setup or forcing a recompile to fix errors on a page. For example when changing a static component into a hydrated one, leading to missing client-side bundles. Another issue is sharing state between components in development, which does work in production.
- Hacky serverless rendering: Elder is primarily designed as static site generator and works as a Node.js server in development. Ideally we’d like to use it for serverless rendering as well. Serverless rendering with Elder is possible, but a bit hacky. Maybe in the future it could work with or like the new Svelte serverless adapters.
- The Elder.js ecosystem is still small: where mature frameworks typically have lots of extensions and example projects, the Elder.js ecosystem is still small. The good thing is that it’s essentially still just Svelte and you can often borrow things from Sapper. And even better is that Elder.js is designed to be extendible using hooks and Elder.js has its own plugins system.
Nick Reese, the creator of Elder, underlines Elder is still in its infancy in Nick’s elaborate blog post on Elder.js. He has a clear idea of things to improve and a roadmap to achieve it. As Elder.js is still a young framework, you can play a part in how it evolves. I personally experienced Nick is very open to new ideas. So give Elder.js a try and get involved!