 Welcome to this talk about Svelte JS. We'll see how we can rethink our existing frontend apps and probably use the patterns that Svelte introduces. Svelte is a framework for building UIs and it's slightly different than the ones that we've been using today. I'm Omang, I'm a frontend engineer at RazerPay and we've been using Svelte since it's version two in production. I'd like to start the talk by speaking about few eras of JavaScript. So people who've been doing frontend for a while you all started with jQuery. jQuery just made it easier to manipulate the DOM, add classes or add elements in the DOM. jQuery was nice because the browser APIs back then were very inconsistent and they were probably ugly to work with. Then came React, it solved the problem that jQuery had. With jQuery, we had our state all over the place and React introduced us to things like creating our UIs in terms of components with their own managed state and React also introduced patterns like composition which are very helpful. jQuery and React both became very popular and gave rise to a lot of third party plugins and libraries that people could use to create all sorts of different UIs and when I say React here, this holds true for other libraries as well like U, Angular and so on. We started using SSR once we realized shipping our entire frontend app was not, our entire frontend app as a JavaScript bundle was not very helpful because the user would end up on a loading screen for a while and it just wouldn't work with our SEOs. We need to ask ourselves what's next. Just like React made the libraries before it seemed what could be the next thing that would make React seem okay. Our frontend apps these days take up a lot of memory because they have a runtime on top of them and they're probably too big to ship over the network. There's a startup that got funded in YC recently that runs Google Chrome on a data center and then streams it on your computer. How did we end up shipping frontend apps that were this memory intensive? Could the new framework that we think about solve these problems could it be, could it not have such a huge memory overhead and could we ship smaller bundles to the users? Could the next framework be swelled? You've probably heard about swelled at JSFOO. It was mentioned a couple of times in the talks as well and if you watched the Google Chrome Dev Summit last year, on day two, the folks at Google were comparing different frameworks and what they've done recently to increase their performances. When they mentioned swelled, all they had to say is it's already super fast and there's not a lot that can be done in this area. I'd like to talk next about reactivity and spreadsheets. Spreadsheets run a lot of the business world and they're extremely powerful. Spreadsheets are super fast as well. So when you're working with a spreadsheet, if you change one thing, it doesn't take a lot of time to update the UI. Compare it to a lot of react apps that we end up shipping. If they have a lot of UI elements, if they have a lot of components that are rendered to the DOM, it becomes jankier over time, but we've probably never experienced this happening with spreadsheets and spreadsheets are also super user friendly. So all you have to do is enter math formula or function and then things just work. Cells just start populating themselves. This is done by using a graph and it's called forward referencing. So for example, you have a cell B that depends on the value of cell A. There's a dependency that the underlying engine has that B depends on the value of A and then every time the value of A changes, the engine knows that it just has to change the value of B and not re-render the entire thing and figure out what has changed. For example, we have a spreadsheet here. The value of cell D4 is a product of cells B4 and C4. And if you look at the graph from B4, B4 has an external B4 outputs to D4. And similarly, C4 would also output to D4. But if you look at the dependencies of D4, it has two inputs and one output. So because the underlying engine has this graph underneath, every time the value of C4 changes, it knows that it has to go ahead and update D4. And because D4 has now changed, we have to go ahead and update D5 as well. We don't re-render the entire spreadsheet in memory and then figure out what has changed. This is also something that reactive programming uses. So in our traditional imperative programming world, if we had to define a relationship between B and A, B is always supposed to be A plus one. Every time that you want to change the value of A, we also have to re-compute manually the value of B. We have to declare that statement. Sure, we could abstract this in a function called set A, which would internally update the value of A and all its dependencies. But as the number of dependencies grows and as it goes deeper, if there was another variable that would depend on the value of C, writing all of these functions and maintaining them probably becomes slightly difficult. But what if we could use another operator that would allow us to define relationships like this? So if we had an R operator like this, which would allow us to say B is supposed to be the value of A plus one, the underlying engine would be able to figure out the relationship between these two and every time that you update the value of A, it would automatically update the value of B. These are probably two of the major propositions behind Svelte. Instead of the R operator, we just use assignment operators like we do now. And instead of re-render the entire thing and computing what has changed, we use like spreadsheets, a dependency graph that tells us what exactly would be changing when we change a certain variable. The next thing is DX versus UX. So good developer experience obviously means we have apps that are easier to write and maintain and there's reason about or if we go through some component, we're able to figure out what it's doing. And good UX is when the user is trying to do something, they're able to get from point A to point B without a lot of jank or without unnecessary waiting times. Good DX and good UX don't necessarily have to be mutually exclusive, but as it stands today, they kind of are react apps have become jankier as it has more components, they become jankier and it's just a slower UX for the end user. And this is especially true on mobile devices where there's not enough processing power. The animations are slightly jankier, it just doesn't work like it does on your machine. I have two snippets here. One is plain old vanilla JS and the other is react. What we're trying to do here is update the name from an input field. The name isn't an H3. So if you look at it from a perspective of what is easier to write and maintenance, of course the react app because we're able to think in terms of components and state. As it scales, writing vanilla JS for all of these components becomes slightly trickier and the number of lines in our source also increases. So it brings a greater surface area for bugs to appear from. But which of this is more performant? I'd say the vanilla JS code, which is directly interacting with the DOM APIs is more performant because there's no underlying runtime or underlying virtual DOM that it has to interact with. While with react as the number of our components increases and we change something on the top, it has to figure out a diff all the way to the nth child in the depth of it and then figure out what has changed. If we compare these side by side, when an input event is fired, if we use the DOM APIs directly, we just go ahead to the DOM element and change the value. But if we're using a virtual DOM, we would have to update the state, re-render the entire V DOM in memory and then reconcel and then figure out what has changed and then actually go ahead and change that value in the DOM. So the last step that we do with the virtual DOM library is the only step that we do with the DOM APIs, which makes DOM APIs very fast for the users, but using a virtual DOM library using the syntax that it provides is obviously better for the users, for the developers. It allows us to ship more features frequently. But what if we couldn't have the best of both worlds? What if we had GSX? We could reason in terms of components and we had all sorts of life cycles so we could do asynchronous things or we could perform side effects, but everything was compiled to native DOM API calls. This means we don't have a runtime in our application. We don't have virtual DOM runtime. We don't have React or view or Angular. We don't have a reconciler that figures out what has changed. This is the primary proposition behind Svelte. Svelte is a compiler. The source code that you write goes through a compiler and a bundle is generated and the code in that bundle interacts directly with the DOM. So instead of having a virtual DOM runtime, on top of the DOM runtime, we directly interact with the DOM runtime. Because we're also not shipping a runtime, we have a smaller bundle size. React GZ with React DOM is about 45 to 50 kbs. So we're saving up on that. And our apps also take faster, apps are also faster to bootstrap because they don't have to go through the entire overhead of virtual DOM stringification. I have this React code here which uses the hooks APIs. It has a counter and it has a name. It displays the name and it has an input field to update the name. There's a button which has the count of the number of times that is clicked and it has a non-click listener which updates account by one every time you updated. The same component in Svelte can be written and just fuel these lines of code. We have a variable name. We pass in a default value or we have a count. We have an each one that displays a name. We have an input element, but this time we bound the value of the input element with that name. So we don't Svelte when it generates the code, it figures out that every time the value of the input field changes, we also have to update the name variable. And within button, we have an on click listener which increases the count by one. So if you notice the count plus one step, we're just reassigning the variable and that's how reactivity works within Svelte. You don't need to call extra functions. Everything just works as reassignments. And if I compare them side by side, the Svelte code is fewer lines of code and it's just closer to HTML to what people learn when they try, when they enter web development than the react component. So this allows people who are not very proficient with building components using react or any other virtual DOM library. They've just learned HTML to write, to build Svelte codes. And this is true in the real world as well. Eliza was a developer at Spotify when she tweeted this. One of our product managers was able to make changes to a Svelte component just because it was closer to HTML and the product manager happened to know some HTML. But all of this is okay. It doesn't make sense if I don't show you a demo on how Svelte makes it easier for us to write apps. We have a, we have a repel here where I'll make, I'll show you how things work. There's some code that I can write here and output here. So basic templating in Svelte is just writing variables within curly braces. We can also add styles by adding a style tag. So I can say I want the H1 to have a color of blue. I can also use other components within my components. So if I have a greeting dot Svelte and it has an H1 that says hello, JSU. I can go ahead in my main component. I can say import greeting from and I can render it as JSX here. This is not technically JSX. It's HTMLX, which is a superset of HTML. So I don't have to close my tags. It just works. I don't have, if I had an input element, I could say bind name, bind value as name. And I wouldn't have to have a closing tag here. So now the app has a name, which is bound to this input field. Every time I change this, this changes. But if you notice the H1 that I have here, the color that I set is not being applied to the H1 within greeting, even though it's being rendered in the same place. So this is something called a scoped CSS that Svelte uses. So when it compiles the CSS, it adds a computer-generated class to the tag and then also to the style. So it's only applied to the markup that lives within the same file. If I got rid of this element, Svelte would show a warning saying unused CSS selector and it would just not have that CSS in the bundle in the output, which means you don't end up shipping unnecessary CSS and you're always able to see what doesn't work. So oftentimes when you refactoring code, there's a lot of CSS that you don't know if it's safe to remove, but when you have these sort of features, the compiler itself is able to tell you that this CSS selector is not being used anywhere and I won't just bundle it for you. I'll get rid of this and what if we want to pass the name to this greeting component? I'll go back here. I'll use my templating, I'll say hello name, but I need to tell this component that it has to accept a name prop, which I can do using export let name, which means it's just expecting a name prop. I can also pass in a default value so that if this is undefined or if the consumer component just doesn't pass a prop, it defaults to world. I'll go ahead here and I'll use the shorthand way to pass a prop. Again, if I go back to result, it will just work. There are also conditionals and loops that Swilt has. So if I wanted to render this only when name had some value, I could do this else and then close my block. I'll show the greeting only if there's any name available. If not, I'll ask the user to please enter a name. So if this is blank, the component just disappears. If not, it comes back into the view. This is probably not how we would want to build apps in the real world. If something was appearing or disappearing out of the screen, you would want animations and transitions to happen. So if I go here and I say import fade and slide from Swilt transition, I could do this, come into the view by feeding and then go out by sliding. So on the same app, it slides out and it feeds in when it has to enter or go out from the DOM. All of this is compiled, all of this is shipped as CSS and the runtime. So any transitions that you see here are running off your main thread so they'll not be zankier and they'll not block your main thread. There's also a concept of computed properties. So if I had a style here, if I had a class say green and it has a color of green, I could have a computed variable here which is supposed to become green only when name has a value of green. And if I wanted this H1 to have a class of green, if the value was green with React, I'd probably do something like this. If green set it to green, otherwise set it as an empty string. This makes sense, but as the number of classes that you want to apply conditionally to the same element goes, this expression that you have here, this expression grows in size and it just becomes slightly uglier. With Svelte, I can say class green, apply the class green, only when this expression evaluates to true. Again, back to these computed properties, what these do is every time the value of name changes, every time the value of its dependencies changes, it is recomputed. So this is where the forward referencing and the dependency graph come in. If I go and look at the JavaScript output, if I go to the update function, if it says if the name has changed, if the name is dirty, invalidate the green, invalidate the green value within the component and set it to the new value. So if the name is green, we add the class, how this works is if I set the value of this input field to green, it adds this class at runtime. This makes sense when you have multiple classes. If I had a class say color red and I had another computed property, red is name equals red. I could go ahead here and I'd say class red. I'm using a shorthand here. So if the class that you want to use has the same name as your variable, you don't have to have an expression. You could just use a smaller directive and it would work again in a very similar way. You can also compose components. So instead of this text here, I could pass in a slot and from within app, I could have a greeting and I could pass in children. Each one is hello, name, this hello name and it would work. We also have stores. Stores are global variables that you can reuse between multiple components. So I'll create a file store.js. I'll import a write table from swell store and I'll export store or name here. And within greeting, instead of having this prop, I could say import name from dot slash store.js and the way that we use stores within our components is by prefixing the references by a dollar sign. So I prefix them both here and if I go back to my app, I'll also import the same name store here. I'll get rid of this. I have my name here and my name here and again, it just should work. Unexpected token, oh, thanks. Legal release and export name. Oh, we forgot to change the reference here. So dollar, again, it works. Red, green, everything. Like the if block that I showed you earlier, there's also an await block that I find really helpful. It is used with promises. So if I look at this code here, I have a promise, which is get random generator. Get random generator just fetches a random number and resolves when it's done. There's a button here. And when I click on the button, it causes this function. What this does is just reassigns the value of promise to the new promise. So this is again, reactivity in action and in the await block, I can await a promise and then once it's resolved, I can render something with its value. So while it's still pending, I can show waiting state and once it's done, I can either show a result. I can show UI corresponding to the result or UI corresponding to the catch. This works. You don't have to have a loading local state within your components. We also have life cycles for mounting and unmounting. So we have a life cycle called on mount, which is invoked when your component has finished mounting. We have a life cycle on destroy, which is invoked when your component is removed from the DOM. So all of these are helpful when you want to perform other side effects, network calls, or what have you, depending on the life cycle. We also have after update and before update, which are executed after and before Svelte has finished recomputing the new values when you're here saying something and exactly before they're rendered to the DOM. We can also have events. So I can add event listeners by on click as a function that could be declared in the script or I could have an inline function. But if I wanted to proxy or to bubble up events back to parent components within my H1, I could just say on click and it would bubble it up back to wherever it's being used from. So within greeting, I could say on click alert something. Cool. So if I click alert something, this helps you create event listeners back from any component. We also have named slots. So instead of just one slot, you can have multiple slots. This removes the need for things like render props because you're able to have multiple children and you're able to define where they're supposed to load back to the presentation. Cool. So there are some differences with react that Svelte has. Svelte is reactive by default and it's reactive by assignments. So it's more closer to the way that you write code. If you're looking, if you're reading code from top to bottom, reassignments would just make more sense. We don't need set states or set X hooks sprinkled throughout our code. So it is compiled to DOM APIs, which means there's literally no runtime. The DOM is our runtime. This makes it faster to push changes to the DOM and faster to bootstrap because you don't have an underlying runtime which needs to recompute what has changed and then shrinkify the virtual DOM. You can declare CSS transitions and it's a very short declarative syntax for that. You have these CSS directives and all of them are compiled to CSS so that none of your animations are blocking the main thread. There's also two way of binding. A lot of people have different opinions about this. One of the key features with react was we only have one way of binding now, but two way binding helps when you're trying to build control input elements or control forms and swell the swell code is closer to HTMLX than JSX. So it looks very similar to HTML people who don't know are you not experienced writing components using react or view or any virtual DOM library would be able to read and understand what's happening in the code itself. We've been using swell since V2 at Razor Pay. It's been about a year now. One of the major products that we use Svelte is Razor Pay Checkout. There are several reasons why we chose Svelte for checkout. Checkout has to have a smaller bundle size. So checkout is the payment widget that we ship to the end customers and that's where customers end up paying. It needs to have a small bundle size because not everyone is on 100 Mbps internet connection and they might be on a 3G that works like 2G. If we are shipping, say react on top of this that would add another 50 KB overhead which is almost half the size of checkout. And checkout needs to be fast. So all 50% of our traffic is from mobile devices more than 50% actually and not all devices are high and they don't have the latest Snapdragon or eight gigs of RAM. People have phones with one gigs or two gigs of RAM and the payment widget appears within the apps that the user is using. So which means it needs to be fast. Web views don't have as much power as our desktops do. Removing a runtime, a virtual DOM library and then using just the native DOM API or the DOM runtime makes it way faster to apply updates and is just easier on the batteries as well. And checkout should also not conflict with the merchants code. So if you were to ship, say react version 16 and the merchants app was somehow using react 14 and there were some issues with sandboxing we could have conflicts with the react versions and things would just not work as they should. Before Svelte, our checkout was built using .js which is a templating library and vanilla.js code. We had native DOM event listeners everywhere and that increased the source code, the lines in our source code by a lot and every time that someone new joined they had to go through this entire app and reason about things in terms of native DOM API calls. But with Svelte we've been able to, also our state was all over the place because we didn't have, everything was DOM APIs and native HTML and we couldn't think about Svelte. It had the same problems as the query did. Using Svelte we have a state in place. We are able to think about our UI in terms of components and we've been able to push twice as many features after shifting to Svelte than we did before. It just makes it easier for people to onboard and start building on top of the code base. There are several advantages which means why you should be using Svelte. Svelte has a short and concise syntax so we have small declarative derivatives for using classes and transitions. We have things like await blocks, loops and conditionals. All of our transitions are compiled to CSS. Again, they don't block your main thread because it solves the CSS, they're never tanky. Reactivity happens by assignments. It's easier to read through. We have scope styles so your styles can live with your markup and you don't have to add extra classes in your code and then namespace your components. It just works. It also tells you that these are the styles that are not being used. We're not shipping them to the end user. DOM is a runtime. There's no secondary runtime on top of DOM so things are way faster with Svelte than they are with React. Because Svelte is compiled, our bundles are smaller and we are able to ship as many features in the library as we want. So for example, if you're not using the transition directive, we just won't ship it into your bundle. If we're using another virtual DOM library, say React and React had to include features around transitions, they would have to ship it to every user with every bundle regardless of whether or not the bundle was using it. So we are able to reshape the features that we don't need and because of that, we can provide as many features as we'd want. But when wouldn't you use Svelte? There are certain drawbacks and reasons on why you shouldn't be using Svelte. You need dot-svelte files for each component. So with React, I'd be able to declare a local component which I'm just using in that specific component but with Svelte, I need a different file for every single component. Composition with Svelte is slightly different than with React, so it might need relearning if you only worked with React or other virtual DOM libraries. The bundle size increases with the number of components but this can be worked around by using code splitting. The bundle size increases because each component is compiled into its own bundle and compiled into its own vanilla.js code which has invalidate functions, event listeners and things that watch the reactivity. We have two-way binding. It's completely optional if you're still in the immutable flow. If you don't like two-way binding, if you prefer one-way binding, you're free to use one-way binding but if two-way binding makes things easier for you or difficult for you, you can opt in or out. There's no official TypeScript support yet. There are ways through which you can integrate TypeScript within your Svelte project but you need to spend some time wiring that up and yeah, wiring that up and then if there are any issues with that, you'd have to work around them by yourself. People are working on adding TypeScript support so it should be here pretty soon. There's also no proper testing libraries. The way that we test, the way that people usually test Svelte components is compile each component into its own bundle and use something like JS DOM or Puppeteer or Cypress. And because Svelte is relatively new, there are fewer plugins. If your app is dependent on third-party plugins for creating different parts of the UI and similar alternatives are not available for Svelte, you might want to steer away from it. Svelte version 3 is just four months old at this point and not a lot of people know Svelte. So if you're building a project that has to be maintained by some other team or some other company, you might want to steer away from Svelte because the people that end up maintaining your app might not know Svelte and may not be willing to spend time to understand how it works. But if I manage to convince you about using Svelte so far, you can get started at the Svelte repel which exists at Svelte.dev slash repel or you can clone the template on your local machine, NPMI and then get started with it. There's more that has been built on top of Svelte. There's a framework called SAPR which is also built by Rich Harris who's built the entire Svelte app. SAPR includes things like server-side rendering, routing and code splitting. So it takes all of the effort away from you and gives you a batteries included framework that you can use to ship apps to production and ship just generally faster. There's also Svelte native project which is built on top of native script which allows you to create mobile apps using Svelte. This is faster than using things like React Native because a lot of the work is already done on the compiler's end and it doesn't happen on the user's end. So again, just like web, it's way faster on mobile devices as well. Thanks for listening to me. You can find more resources about Svelte at Svelte.dev. There's also a nice tutorial there that guides you through every single feature that Svelte has. I can be found on at umangumat Twitter if you want to discuss anything about Svelte. Any questions? It's a really nice talk. I would, I want to know that why to use this library when we have P-React where we can have smaller bundle size. Sure. Why not to use P-React or other variant of Freex where we can get smaller bundle size? Because there are two things. First is we want the performance app and the second thing is we want the smaller bundle size. But we can get both of those things from the P-React or other React variants and then we can also get the whole React ecosystem for us. So why to use this library instead of the other variants of React? React is smaller in size. It's just three KBs when you GZip it but it also suffers from the same performance overhead of having another virtual DOM runtime that's running on top of your actual DOM. So if Svelte apps are generally faster than any of the virtual DOM apps that you have. Yeah, that's, that's a trade-off. Just one follow-up question. What I think is that most people don't care whether their application is fastest. They just want their application to be fast enough. So I guess React is mature enough to provide us fast enough web applications. So I don't think there is much benefit of switching to it instead of the library. Fast enough here is pretty subjective. Apps might be fast enough on a 16 GB Mac but if you're running your web app on a POS terminal or on an Apple Watch it may not have as much memory as your own dev machine or the regular users of your apps. If you're shipping B2B apps you might not care about performance but if you're shipping consumer-grade apps like we ship checkout which has to work fast on the end, consumers device which may not be as powerful as our dev machines it makes sense to have faster applications there. It's also more battery-friendly if your apps are generally faster. Thank you. One thing I was concerned about is how is the state management community around Svelte. So React has Redux, Mobix and all those particular libraries with it, right? That there's React Redux and there's a Mobix state tree for React. So for Svelte how do you go about it when you have more state for a complex application? Which makes- I am not sure about the third-party libraries but Svelte has support for context APIs which is very similar to React's own context APIs and things like store where you can have a shared state in a different file and then use it in the components that actually need it. But yeah, there might be other libraries around Svelte which are similar to React but I've not used or searched about any of them yet. Hey, hey man, great talk. So just wanted to understand what do you think is basically hindering mass adoption for at this point for Svelte? Like the points you talked about they obviously sound great, right? So like, why do you think the adoption at this point is- Is it just the learning curve or are there other factors? It's probably not the learning curve. I'd argue that if you were starting out by, if you were just starting out learning how to create web apps, Svelte would probably have a less steep learning curve than say something like React would but from what I believe the most, the two factors that hinder mass adoption right now is there are not a lot of third-party libraries that you can use, that you might already be using and Svelte is just four months old. Svelte 3 is just four months old so there might be some issues that you might encounter as the library, as the framework matures, the adoption will definitely increase. Okay, so do you recommend like, so if I go back to my front-end team, do you recommend making the switch at this point considering the ecosystem is probably not that mature? If you do not need third-party libraries and if you're just building something out that is not that intensive if you're doing a POC that may or may not be shipped to production, I would definitely recommend using Svelte because it's a better experience even while writing it. Yeah, hi. Your thoughts on web components? I personally not worked with web components but if you were asking specifically in terms of Svelte, Svelte has a way to compile directly to web components. It has had support for web components since V2. A lot of its API slots is also inspired by how web components work.