Is Svelte the future of JavaScript Frameworks?




Over the years, JavaScript development has gone through several paradigms: from raw AJAX in vanilla JS to a long reign of event-driven frameworks such as jQuery and Mootools, to the current state-driven approach of the current champions such as React, Vue, and Angular. 





But in an era where everyone is looking at performance, accessibility, and developer experience, there’s a new contender that promises to deliver all of these through a radical new approach to building apps. Is Svelte the next big thing in JavaScript frameworks? 





The Evolution of JavaScript Frameworks





In one way or another, we’ve been building web apps even before the word “app” was coined.





Early interactive websites gathered the power of AJAX to provide improved navigation and even what we may call the first SPAs. But the crude state of JS made for an excruciating developer experience, making apps increasingly hard to deploy and maintain as they grew.





In 2006 John Resig created jQuery, and the era of event-driven frameworks was born. After a quick challenge with MooTools, jQuery rose as the go-to framework for anything front-end, and it reigned supreme for a good decade. 





But as applications grew bigger and more complex, the need to share data across components drove a paradigm shift towards other approaches. After a brief and quick burn of Ember and AngularJS, we ended up with the current champions, that in one way or another aim towards a declarative, state-driven approach to frontend development: React, Vue and Angular. 





React is currently the most used and one of the most sought-after skills in all of tech, which provides an incredibly rich environment, a ginormous user base, and pretty much a guaranteed job for anyone that learns the ins and outs of the library. 





This has its downsides too, most notably developers using React for places where it may not be the best option. We see simple institutional websites built with React and a bunch of add-ons all the time, something that honestly feels like driving a nail with a sledgehammer: sure, you’ll get the nail in, but you’ll probably take a good chunk of the wall with it. But even in applications that really need a tool like React, it’s easy to find bundle sizes getting out of control, contrived codebases with increasingly painful developer experience, and certain patterns where the user experience is seriously damaged by poor performance.





What is Svelte?





That’s where Svelte.js promises a bright new future, by providing incredibly lightweight and performant applications.





The key idea that allows it to do so is working as a compiler. Current frameworks/libraries ship with your bundle to run your declarative code in the imperative programming environment of the browser APIs. 





Svelte works as a compiler at build time instead, cutting down a huge chunk out of your bundle size. It only ships your code, with some enhancements introduced by the framework. 





But it doesn’t stop there. It also allows us to write far more efficient code by achieving true reactivity, something that no other library/framework comes even close to and provides a smooth developer environment that’s incredibly easy to work with, maintain, and scale. 









The Developer Experience Matters





One of the biggest challenges for any framework is providing a good developer experience. We don’t really build applications for the computers but for other humans, and that includes both the users and our fellow developers. 





There are a million things that influence how a system’s developer experience is perceived, but we can probably summarise a positive experience as providing an easier learning curve, better readability, less boilerplate, doing more with less code, and ease of maintenance. 





I would dare to say that the focus on developer experience is actually one of the main reasons why Vue was able to achieve such great success in a market dominated by frameworks/libraries built by industry giants, and why it’s so heartwarmingly valued by its users.





Svelte has put a great effort into this, leveraging the lessons learned from previous frameworks. It takes ideas from Vue such as single file components and even revendicates the old jQuery motto “write less, do more”. 





Vue-Like Single-File Components





Generally speaking, one of the most welcomed features of Vue is the use of single-file components, that is, the possibility to have our markup, styles, and logic all gathered in one place. Of course, like anything in tech, this is opinionated and has lots of asterisks and “it depends” attached to it, but for the most part, developers value the readability and modularity of SFCs. 





Svelte.js takes inspiration from Vue here and gets it to the next level. In any given .svelte component you can have a



Hello {title}!


This is my first Svelte component





This is one of the things that in my opinion makes Svelte so welcoming for newbies: if you know HTML, CSS and JS, Svelte will look familiar the very first time you see it. And to prove it, check this bit of (slightly more complex) code and see if you can understand what it does:











Pretty sure most people reading this, even those who have never seen Svelte code before but are familiar with HTML and JS, will immediately pick that we have a button that displays how many times it was clicked and updates through an event handler. 





Sure, some parts of the JavaScript syntax can get obscure (more on this later on), but it will still be relatively easy to understand. With Svelte there’s no need to learn a whole additional templating language like React’s JSx or understand the totality of the system before dropping a line of code as in Angular’s case. 





Scoped, Modular CSS





One of the biggest challenges of styling websites and apps is keeping control over the CSS specificity and scopes. As apps grow bigger, it’s fairly common to see blocks of CSS that no one dares to delete or modify, simply because you don’t know what it will affect. 





The Svelte framework addresses the issue by having your styles scoped to the module you declare them in by default.  You can add a





/* Nested.svelte */

This is another paragraph.





We have two modules, one nested in the other. The resulting app will show two paragraphs, but only the first one will be purple. If you inspect the compiled code to check how things are working under the hood, you’ll see that Svelte is creating a unique class, something among the lines of p.svelte-urs9w7{color:purple;}, and only applying it to the

elements explicitly declared in that module.





While I can see the huge benefit this provides for most teams, if you have a dedicated CSS specialist they’re probably yelling “just embrace the cascade instead” right now. I know I would… Well, turns out you can. 





Svelte doesn’t lock you into this architecture. You still have the option to affect nested elements with '));e.each(function(){var e={};if(e.sidebar=i(this),e.options=t||{},e.container=i(e.options.containerSelector),0==e.container.length&&(e.container=e.sidebar.parent()),e.sidebar.parents().css("-webkit-transform","none"),e.sidebar.css({position:e.options.defaultPosition,overflow:"visible","-webkit-box-sizing":"border-box","-moz-box-sizing":"border-box","box-sizing":"border-box"}),e.stickySidebar=e.sidebar.find(".theiaStickySidebar"),0==e.stickySidebar.length){var a=/(?:text|application)\/(?:x-)?(?:javascript|ecmascript)/i;e.sidebar.find("script").filter(function(i,t){return 0===t.type.length||t.type.match(a)}).remove(),e.stickySidebar=i("

").addClass("theiaStickySidebar").append(e.sidebar.children()),e.sidebar.append(e.stickySidebar)}e.marginBottom=parseInt(e.sidebar.css("margin-bottom")),e.paddingTop=parseInt(e.sidebar.css("padding-top")),e.paddingBottom=parseInt(e.sidebar.css("padding-bottom"));var n=e.stickySidebar.offset().top,s=e.stickySidebar.outerHeight();function d(){e.fixedScrollTop=0,e.sidebar.css({"min-height":"1px"}),e.stickySidebar.css({position:"static",width:"",transform:"none"})}e.stickySidebar.css("padding-top",1),e.stickySidebar.css("padding-bottom",1),n-=e.stickySidebar.offset().top,s=e.stickySidebar.outerHeight()-s-n,0==n?(e.stickySidebar.css("padding-top",0),e.stickySidebarPaddingTop=0):e.stickySidebarPaddingTop=1,0==s?(e.stickySidebar.css("padding-bottom",0),e.stickySidebarPaddingBottom=0):e.stickySidebarPaddingBottom=1,e.previousScrollTop=null,e.fixedScrollTop=0,d(),e.onScroll=function(e){if(e.stickySidebar.is(":visible"))if(i("body").width()e.container.width())return void d()}var n,s,r=i(document).scrollTop(),c="static";if(r>=e.sidebar.offset().top+(e.paddingTop-e.options.additionalMarginTop)){var p,b=e.paddingTop+t.additionalMarginTop,l=e.paddingBottom+e.marginBottom+t.additionalMarginBottom,f=e.sidebar.offset().top,h=e.sidebar.offset().top+(n=e.container,s=n.height(),n.children().each(function(){s=Math.max(s,i(this).height())}),s),g=0+t.additionalMarginTop,S=e.stickySidebar.outerHeight()+b+l0?Math.min(y,g):Math.max(y,p-e.stickySidebar.outerHeight()),y=Math.max(y,u),y=Math.min(y,m-e.stickySidebar.outerHeight());var v=e.container.height()==e.stickySidebar.outerHeight();c=(v||y!=g)&&(v||y!=p-e.stickySidebar.outerHeight())?r+y-e.sidebar.offset().top-e.paddingTop<=t.additionalMarginTop?"static":"absolute":"fixed"}if("fixed"==c){var x=i(document).scrollLeft();e.stickySidebar.css({position:"fixed",width:o(e.stickySidebar)+"px",transform:"translateY("+y+"px)",left:e.sidebar.offset().left+parseInt(e.sidebar.css("padding-left"))-x+"px",top:"0px"})}else if("absolute"==c){var T={};"absolute"!=e.stickySidebar.css("position")&&(T.position="absolute",T.transform="translateY("+(r+y-e.sidebar.offset().top-e.stickySidebarPaddingTop-e.stickySidebarPaddingBottom)+"px)",T.top="0px"),T.width=o(e.stickySidebar)+"px",T.left="",e.stickySidebar.css(T)}else"static"==c&&d();"static"!=c&&1==e.options.updateSidebarHeight&&e.sidebar.css({"min-height":e.stickySidebar.outerHeight()+e.stickySidebar.offset().top-e.sidebar.offset().top+e.paddingBottom}),e.previousScrollTop=r}},e.onScroll(e),i(document).on("scroll."+e.options.namespace,function(i){return function(){i.onScroll(i)}}(e)),i(window).on("resize."+e.options.namespace,function(i){return function(){i.stickySidebar.css({position:"static"}),i.onScroll(i)}}(e)),"undefined"!=typeof ResizeSensor&&new ResizeSensor(e.stickySidebar[0],function(i){return function(){i.onScroll(i)}}(e))})}(t,e),!0)}function o(i){var t;try{t=i[0].getBoundingClientRect().width}catch(i){}return void 0===t&&(t=i.width()),t}return(t=i.extend({containerSelector:"",additionalMarginTop:0,additionalMarginBottom:0,updateSidebarHeight:!0,minWidth:0,disableOnResponsiveLayouts:!0,sidebarBehavior:"modern",defaultPosition:"relative",namespace:"TSS"},t)).additionalMarginTop=parseInt(t.additionalMarginTop)||0,t.additionalMarginBottom=parseInt(t.additionalMarginBottom)||0,function(t,o){e(t,o)||(console.log("TSS: Body width smaller than options.minWidth. Init is delayed."),i(document).on("scroll."+t.namespace,function(t,o){return function(a){var n=e(t,o);n&&i(this).unbind(a)}}(t,o)),i(window).on("resize."+t.namespace,function(t,o){return function(a){var n=e(t,o);n&&i(this).unbind(a)}}(t,o)))}(t,this),this}}(jQuery); /*! MenuIfy by Templateify | v1.0.0 - https://www.templateify.com */ !function(a){a.fn.menuify=function(){return this.each(function(){var $t=a(this),b=$t.find('.LinkList ul > li').children('a'),c=b.length;for(var i=0;i');}}if(h.charAt(0)==='_'){d.text(h.replace('_',''));d.parent().appendTo(m.children('.sub-menu'));}}for(var i=0;i');}}if(k.charAt(0)==='_'){f.text(k.replace('_',''));f.parent().appendTo(n.children('.sub-menu2'));}}$t.find('.LinkList ul li ul').parent('li').addClass('has-sub');});}}(jQuery); /*! ResizeIfy - LazyIfy on Scroll by Templateify | v1.5.0 - https://www.templateify.com */ !function(o){o.fn.lazyify=function(){return this.each(function(){var t=o(this),a=o(window),n=t.attr("data-image"),e="w"+Math.round(t.width()+t.width()/10)+"-h"+Math.round(t.height()+t.height()/10)+"-p-k-no-nu",r="";n.match("resources.blogblog.com")&&(n=noThumbnail),r=n.match("/s72-c")?n.replace("/s72-c","/"+e):n.match("/w72-h")?n.replace("/w72-h72-p-k-no-nu","/"+e):n.match("=w72-h")?n.replace("=w72-h72-p-k-no-nu","="+e):n,t.is(":hidden")||a.on("load resize scroll",function o(){if(a.scrollTop()+a.height()>=t.offset().top){a.off("load resize scroll",o);var n=new Image;n.onload=function(){t.attr("style","background-image:url("+this.src+")").addClass("lazy-ify")},n.src=r}}).trigger("scroll")})}}(jQuery); /*! jQuery replaceText | v1.1.0 - http://benalman.com/projects/jquery-replacetext-plugin/ */ !function(e){e.fn.replaceText=function(n,t,i){return this.each(function(){var o,r,l=this.firstChild,u=[];if(l)do{3===l.nodeType&&(r=(o=l.nodeValue).replace(n,t))!==o&&(!i&&/