my-experience-with-svelte.mdx
1 --- 2 title: My Experience Trying Out Svelte For The First Time 3 date: 2020-09-27 4 description: Phew lads, I finally tried svelte after a while and boi oh boi do I love it 5 tags: 6 - svelte 7 - website 8 --- 9 10 import Update from "~/components/Update.astro"; 11 12 # Introduction 13 14 Phew lads, I finally tried using Svelte and boi oh boi was it an awesome experience. I've been holding my self to try svelte because the editor that I'm using which is **Neovim** doesn't support svelte really well back then. I decided to try it again this time and it works great now. 15 16 # Why Svelte? 17 18 If you don't know, I usually use React for building a website. I love React and its concept but I want to try something else that is different. Why not Vue? you might ask. Well, to be honest it's hard for me to wrap around my head on how Vue works. It's also because Svelte is quite a new library and it is unique. It doesn't use Virtual DOM like most of SPA framework does. 19 20 To be fair, Svelte is [actually a language](https://gist.github.com/Rich-Harris/0f910048478c2a6505d1c32185b61934) that compiles to pure javascript that we all know and _~~hate~~_ love. There are other languages that also tries to desribe interactive user interface such as [Imba](https://www.imba.io/), [Elm](https://elm-lang.org/), [Marko](https://markojs.com/) and many more. 21 22 # My Experience 23 24 ## Almost feel like not using any framework 25 26 My first impression was like, man, this is just like a vanilla html with some sugar on top of it. It looks similar to Vue syntax but more flexible so to speak. Vue's html has to be placed inside of `<template/>` tag whereas Svelte isn't. You can place it literally anywhere. Take a look at this. 27 28 ```html 29 <style> 30 .heading { 31 color: aqua; 32 } 33 </style> 34 35 <Navbar title="An epic title"> 36 <h1 class="heading"> 37 {heading} 38 <h1> 39 <div> 40 <p>{paragraph}</p> 41 </div> 42 <footer /> 43 44 <script> 45 import Footer from "./_components/Footer.svelte"; 46 let heading = "This is a heading"; 47 let paragraph = "This is a heading"; 48 </script> 49 </h1> 50 </h1></Navbar 51 > 52 ``` 53 54 It looks very similar to pure html isn't it? I also prefer Svelte syntax over Vue syntax because it looks more similar to React. What I mean by that is, if you want to run a javascipt expression, they both uses `{}`. For example. 55 56 ```html 57 <!-- React --> 58 <Counter count="{count}" /> 59 60 <!-- Svelte --> 61 <Counter count="{count}" /> 62 <!-- or shorthand if you prefer --> 63 <Counter {count} /> 64 65 <!-- Vue --> 66 <Counter v-bind:count="count" /> 67 ``` 68 69 ## What I've made with Svelte 70 71 I've made 2 websites using Svelte. The first one is [Three Of Something](#) which is a place where I put the result of small challenge where I implement a UI design that I found to code. I do this challenge every week with both of my friends, [NikarashiHatsu](https://github.com/nikarashihatsu) and [LynSotera](https://github.com/LynSotera). Here's a screenshot of the homepage. 72 73  74 75 Go visit the website if you're interested ツ 76 77 The second website that I made is [Kanaizu](#). It's basically some sort of quiz app where you need to type the correct romaji for the shown kana. The main reason of why I made this app is because I want to learn more about Svelte and to help my friend memorise Japanese kana. Here's the homepage of it. 78 79  80 81 Again, go visit the website if you're interested ツ 82 83 To be fair, I made those using [Routify](https://routify.dev/). Basically, **Routify handles the routing**. I didn't use [Sapper](https://sapper.dev) because it's too much for what I need. I just need a basic routing and Routify is perfect. 84 85 ## What I've learned so far 86 87 After making those 2 sites, I of course learned some new stuff and I'm so happy that I finally decided to try Svelte. 88 89 ### Components 90 91 On React, a component is a function that returns a JSX. It looks something like this. 92 93 ```javascript 94 export default () => <p>Hello World!</p>; 95 ``` 96 97 On Svelte, the whole file is a component. It uses `.svelte` extension and the syntax is basically a superset of HTML. It looks something like this. 98 99 ```html 100 <style> 101 /* some stylings */ 102 </style> 103 104 <div>I'm an HTML</div> 105 106 <script> 107 // some logic goes here 108 </script> 109 ``` 110 111 The order doesn't really matter but I prefer `style-markup-script` because I like the markup to be in the middle of the stylings and the script. 112 113 ### Props 114 115 Apparently, props in svelte is just an exported `let` variable. So what you would do to make a prop is something like this. 116 117 `Counter.svelte` 118 119 ```html 120 <div>{count}</div> 121 122 <script> 123 export let count; 124 </script> 125 ``` 126 127 `App.svelte` 128 129 ```html 130 <div> 131 <Counter count="{1}" /> 132 </div> 133 134 <script> 135 import Counter from "./counter.svelte"; 136 </script> 137 ``` 138 139 ### Scoped stylings 140 141 Styling in Svelte is scoped! Because you write the styling on the same file as the rest of the component, it became scoped. You can still change the global styling using `:global()` though. 142 143 ### Global state 144 145 Next thing that I learned is global state or store. Usually in React, I need `React.Context` to store a global state. On Svelte, I need to use `svelte/store`. Global state is much simpler in Svelte in my opinion. Here's a comparison between them. 146 147 `context.js` 148 149 ```javascript 150 import React, { createContext, useState } from "react"; 151 152 export const CountContext = createContext(null); 153 154 export const CountProvider = ({ children }) => { 155 const [count, setCount] = useState(0); 156 return <CountContext.Provider value={{ count, setCount }}>{children}</CountContext.Provider>; 157 }; 158 ``` 159 160 `app.js` 161 162 ```javascript 163 import React, { useContext } from "react"; 164 import { CountProvider, CountContext } from "./context"; 165 166 export default () => { 167 const { count, setCount } = useContext(CountContext); 168 return ( 169 <CountProvider> 170 <p>{count}</p> 171 <button onClick={() => setCount(count + 1)}>Increment</button> 172 <button onClick={() => setCount(count - 1)}>Decrement</button> 173 </CountProvider> 174 ); 175 }; 176 ``` 177 178 Well, it looks like a lot but it's actually quite simple if you know how React Context works. Now let's compare it with Svelte. 179 180 `stores.js` 181 182 ```javascript 183 import { writable } from "svelte/store"; 184 185 export const count = writable(0); 186 ``` 187 188 `app.svelte` 189 190 ```html 191 <p>{$count}</p> 192 <button on:click="{count.update(n" ="">n + 1)}>Increment</button> 193 <button on:click="{count.update(n" ="">n - 1)}>Decrement</button> 194 195 <script> 196 import { count } from "./stores"; 197 </script> 198 ``` 199 200 I mean, just look at how simple it is. Bare in mind that this post isn't meant to explain every single thing that Svelte has to offer so please refer to the [official website](https://svelte.dev/tutorial/writable-stores) for more explanation ツ 201 202 Actually, Svelte also has [Context API](https://svelte.dev/tutorial/context-api). Since I'm still learning, please read [this article](https://medium.com/better-programming/6-ways-to-do-component-communications-in-svelte-b3f2a483913c) for better understanding. It's such a good article and you should definitely check it out! 203 204 ### Animation and transition directive 205 206 Svelte provides [animation](https://svelte.dev/tutorial/animate) and [transition](https://svelte.dev/tutorial/transition) that you can use to animate your components. The usage is also simple, what you would do is just something like this. 207 208 `Transition.svelte` 209 210 ```html 211 <button on:click="{isVisible" ="!isVisible}">Toggle</button> 212 {#if isVisible} 213 <p transition:fade>This text is visible</p> 214 {/if} 215 216 <script> 217 import { fade } from "svelte/transition"; 218 let isVisible = false; 219 </script> 220 ``` 221 222 The transition directive is triggered whenever an element leaves or enter the DOM tree. More details about transition directive is available [here](https://svelte.dev/docs#transition_fn). 223 224 I used transition for [Kanaizu](#) but I haven't tried the animate directive since I haven't found the use case for it. 225 226 ### Logic blocks 227 228 Last one is logic blocks. On React, you can use curly braces `{}` to write some Javascript logics and return something that will get rendered. Here's an example. 229 230 ```javascript 231 import React, { useState } from "react"; 232 233 export default function Counter() { 234 const [isVisible, setVisible] = false; 235 return ( 236 <div> 237 {isVisible && <div>I'm Visible!</div>} 238 <button onClick={() => setVisible(!isVisible)}>Toggle</button> 239 </div> 240 ); 241 } 242 ``` 243 244 It's a little bit different on Svelte. It looks something like this. 245 246 ```html 247 {#if isVisible} 248 <p>I'm Visible!</p> 249 {/f} 250 <button on:clock="{isVisible" ="!isVisible}">Toggle</button> 251 252 <script> 253 let isVisible = false; 254 </script> 255 ``` 256 257 I like them both so it doesn't really matter. There's also quite a few on [Svelte's docs](https://svelte.dev/docs#if). 258 259 # Conclusion 260 261 Well, I fell in love with this _language_. It's so simple yet it's so good. Sorry if the highlighting looks weird in this post because I couldn't make it work for Svelte or JSX syntax :p 262 263 I want to rebuild this blog using [Sapper](https://sapper.dev) + [MDSveX](https://mdsvex.com/) in the future. Don't get me wrong, [Gatsby](https://www.gatsbyjs.com/) is great. I just want to try out something new. <i style="color: #eaeaea">Svelte's bundle size is also smaller compared to React, that's also why ツ</i> 264 265 <Update date="2020-11-01"> 266 267 If you're reading this then you're currently at my 'new' website that I mentioned earlier =) 268 269 </Update> 270 271 Thanks for reading this! You should definitely try Svelte, you wouldn't regret it. Anyway, have a good day folks! =)