https://cprimozic.net/blog/trying-out-sveltekit/ hamburger menu icon cprimozic.net | @ameobea10 cprimozic.net @ameobea10*Portfolio*Contact*Blog*Professional Experience My Evaluation of SvelteKit for Full-Stack Web App Development Subscribe to Blog via RSS [svg] * TL;DR + Should You Use It? * Motivation * Ecosystem * Background + Demo Application * SvelteKit's Stack + Build Tooling + Server Runtime + Frontend Runtime + Codegen * Development Experience * Conclusion I recently tried out SvelteKit for the first time. This is a summary of my experience setting it up, some information I've collected while researching + learning it, and my thoughts on how it compares to other similar frameworks. If you're not familiar with it, SvelteKit is a framework for building full stack web apps. It builds on top of Svelte and provides a Jamstack environment with support for modern features like server-side rendering, link pre-loading, and static page pre-rendering out of the box. Similar frameworks include Next.JS and Gatsby which both use React, and Nuxt.js which uses Vue. I'm not going to focus on individual features or provide a guide on how to use SvelteKit. The official SvelteKit docs have all of that in detail. TL;DR SvelteKit presents a fresh take on modern web development with everything in one place. It's quite opinionated like Svelte itself, but it's very well designed and has picked the best parts of the frameworks and tools that have come before it. Experienced web developers should be able to adopt it and find familiar patterns. The framework provides a lot of functionality for things like built-in API endpoints, server-side rendering, routing, and similar, but you only have to use the pieces you want. It works just as well for simple, 100% static sites as it does for complex full stack apps with extensive backend logic. It feels much like Rust vs. C++. Rather than adding layers upon layers to existing infinitely backwards-compatible software, it takes the best patterns and features and builds them from the ground up. The result is a vastly simpler, faster, leaner, and easier to use stack that's still familiar to users of most popular modern tooling. That being said, as is made clear in docs and reference in many places, SvelteKit is still unfinished and changing rapidly. I'm reminded a lot of my experiences working with Rust nightly a few years ago and early versions the Rust Language Server. API breakages still happen pretty often and bugs crop up in various pieces. Adoption is still very low but growing rapidly. Almost all of the issues I ran into are intensely fixable things and will likely be smoothed over as SvelteKit moves towards 1.0 and more people adopt the framework. Should You Use It? If you're willing to deal with some early-adopter annoyances and potentially update your code to accommodate breaking changes, it's certainly very usable and probably easier to get started with than alternatives. If you're thinking about trying it out at work or for some serious production application you're going to be stuck maintaining for the long term, maybe wait for the 1.0 release (coming sometime this year, I think). I myself will be reaching for it as a first choice for the next personal project web apps I create in the future. It's a joy to work with and it feels like a piece of the future of web development to me. Motivation I'm an experienced full-stack web developer. I've become very comfortable with my stack of choice (React + maybe Redux + WebPack for frontend, Rust + Rocket for backend). I can crank out React code like nobody's business and the patterns are burnt into my brain. And that worries me a bit! Frontend tech notoriously evolves at an extreme pace, and I love being ahead of the curve. I recently read a Cloudflare blog post announcing full-stack support for their Cloudflare Pages product. One thing that stuck out to me was that they stated prominently that Cloudflare Pages is integrated with SvelteKit out of the box. I had heard of Svelte before, but I had never tried it out. This pushed me over the edge to give it a proper try. I tried out Svelte by itself, building some small components for my in-browser audio synthesis platform, and was very impressed. The patterns were instantly familiar to me coming from a React background. I also found some great articles available for learning Svelte for React devs that greatly accelerated my learning. After that, I decided to give SvelteKit itself a try too, and this is the result! Ecosystem SvelteKit is still in beta, and hasn't reached its big 1.0 milestone yet. It is the successor to Sapper, which isn't extremely popular itself with ~25k monthly downloads on StackOverflow and never hit 1.0 itself. Right now, the amount of people and organizations using SvelteKit is quite low at the time of writing (early January 2022). SvelteKit itself and most of the supporting libraries have very low weekly downloads on NPM and few Github stars. A screenshot of SvelteKit download counts on NPM, showing 33,280 weekly downloads As I mentioned earlier, the thing that got me to try out SvelteKit in the first place was a Cloudflare blog post announcing full-stack support for their Cloudflare Pages platform which included out-of-the-box integration with SvelteKit. That's a big endorsement; Cloudflare has been putting a ton of effort into evolving the state of the art in web app development and deployment, fleshing out their app platforms to compete with the big cloud providers, and bringing new paradigms to the mainstream. I see Cloudflare betting on SvelteKit for their product at this early stage as a very positive signal. Cloudflare's blog post's release date (2021-11-17) seems to coincide almost exactly with inflection points in the growth rate of all SvelteKit-related libraries on NPM, bringing lots of people (like me) into the ecosystem. The @sveltejs/adapter-cloudflare package itself was released then and has seen fast growth ever since: A screenshot of the download counts for the @sveltejs/ adapter-cloudflare package on NPM showing 12,382 weekly downloads On the other hand, the efforts of Cloudflare and other commercial serverless providers seems to be exerting influence on the development priorities of SvelteKit. The only "officially-supported" SvelteKit adapters are for commercial serverless platforms including Cloudflare, Vercel, and Netlify. These all have more weekly downloads than the node adapter, indicating to me that development of SvelteKit will likely continue focusing on these commercial platforms. I enjoy hosting my own software, and being able to run my software independently of any given provider or host is important to me. Although I had no trouble getting the standalone @sveltejs/ adapter-node working and hosting it on my own server, this situation is something I'll continue to monitor going forward. A screenshot of the download counts for the @sveltejs/adapter-node package on NPM show 8,177 weekly downloads Background + Demo Application I decided to build a full-stack to-do application to test out SvelteKit. I'd never actually built one before, but it's the de-facto demo application for a reason. I was already sold on Svelte as a UI framework, and I wanted to focus on the things that make it unique so I didn't spend much time creating an elaborate frontend or adding a lot of features. As a result, the UI really is nothing special: todo app Nonetheless, can try it out for yourself if you want and check out the generated code: https://sveltekit-todo.ameo.dev The full source code is here: https://github.com/ameobea/svelte-todo I went with SQLite for a database to keep with the minimal theme, motivated by a lobste.rs post I read recently. I used the better-sqlite3 package, and it was easy enough getting it set up. I'm sure I could have brought it in with an ORM or something if I wanted as well. I used a bare-bones HTTP basic auth setup to authenticate mutable endpoints. Using basic auth was honestly really great and extremely simple to set up; I'll be using that again for demo or personal projects in the future for sure. SvelteKit's Stack I come from a background of React + webpack, which I've been using since I first learned React around 2017. I've also used Gatsby, which is more similar to SvelteKit and is what this blog was created with. For Node.JS webservers, I've only ever used express. I was curious what kind of tooling SvelteKit was using under the hood, and I didn't see a ton of info in the various guides and readmes. So, I dug a bit into the code. Build Tooling At the top level, SvelteKit integrates tightly with something called Vite. Vite is a build tool that covers much of the same functionality as webpack such as bundling, dev server hosting, and HMR along with a lot of things that are provided by webpack plugins. It has a plugin interface that is compatible with rollup, so you can use rollup plugins with Vite and I expect there's a good amount of crossover between the two communities. Vite handles all the entrypoints for commands like npm run dev and npm run build. The main integration between Vite and SvelteKit comes via vite-plugin-svelte. This plugin handles compilation of Svelte code and a ton of other things to generate bundled and ready-to-deploy output for both the frontend and the backend. Additionally, vite-plugin-svelte pulls in esbuild, "an extremely fast JavaScript bundler" written in go, as a dependency. I couldn't find exactly where it was used in the code or what it was doing, but it's what shows up in my terminal tab when I run yarn dev so it must be running down there somewhere. A screenshot of my terminal tab showing that esbuild runs under the hood when running the yarn dev command This is a pretty tall stack compared to what I'm used to of just running webpack build or similar, and I'd never used any of its components before this. Despite being a tall stack with lots of libraries and tools, SvelteKit's build stack is extremely fast for both dev and production builds. Webpack builds have sped up 2-5x over the past couple of major versions for me, and this feels 10x faster than that. A full production build of both the frontend and backend for my (admittedly trivial) todo app took 1.36 seconds. Starting up the dev server takes well under a second, and hot reloads are just about as instant as I can perceive. Server Runtime I was also curious about what kinds of software was being used to power the server that handles server-side rendering, dynamic backend API endpoints, and static file serving. I'm using the @sveltejs/adapter-node adapter which creates a standalone webserver rather than integrating with Cloudflare Pages or similar. Its source code is actually very short, like ~300 lines short. It uses a Node library called polka which describes itself as "a micro web server so fast, it'll make you dance". The polka server wraps a handler created using sirv for static file serving. I was surprised to see that the Polka Github repository is very inactive with the last commit being 8 months ago. Maybe that's just a sign that it's simple, stable, works well, and doesn't need much maintenence. For endpoints and SSR, all of that is taken care of by SvelteKit itself. I looked at the generated code in the build/server directory after running npm run build and discovered that it too was using polka to serve the backend endpoints and server-side rendering. Gzip compression is enabled by default for the webserver, and cache headers were set on cachable assets by default too. It seems that there is brotli support in there, and it even looks like it's enabled explicitly in the source code for the node adapter. However, it doesn't seem to be working for whatever reason. Maybe there's a magic config option to turn it on somewhere. Everything is being served with HTTP/1 with no HTTP/2 let alone HTTP/ 3 support from the webserver and no apparent way to enable it Because of this, you'll likely want to use SvelteKit behind a load balancer or proxy server that will set these things up if you're not going to use a commercial serverless provider like Cloudflare or Netlify. Everything looked quite light-weight and minimal which was nice to see. The layers between user-created code and the server framework are thin and clear. Frontend Runtime + Codegen SvelteKit emits raw import {...} directives in the generated JS and generates code with