Comparison of major features in SvelteKit vs NextJS.
Goals: fast, easy, convention over configuration, & batteries included. Overwhelming choices are bad versus providing a clear path forward.
SvelteKit | NextJS | Winner | Notes | |
---|---|---|---|---|
UI lib | Svelte | React (or MillionJS or Preact) |
SvelteKit | Svelte offers faster DOM updates, smaller KB client size, much easier cross-component state management, ability to abstract responsive state into external files, etc. Svelte5 has Runes (signals) π, React does not have an equivalent yet. |
Dev: Hot reload | π’ | π’ | -- | I.e. Auto reload on file save. |
Dev: O(1) hot reload | π’ Vite | π’ π§ Turbopack (*not enabled by default) | SvelteKit | I.e. Processes only the changed files. Fast even in big projects. *Update package.json to enable Turbopack: "dev": "next dev --turbo" . |
Dev: "Fast refresh" | π’ π§ (not enabled by default) | π’ | NextJS | I.e. UI state preserved across reloads. |
Dev: Write modern JS | π’ | π’ | -- | |
Dev: A11y console hints | π’ | β | SvelteKit | |
Dev: Prettier | π’ | π’ | -- | For .svelte or .jsx files, respectively. For SvelteKit, install Svelte for VSCode extension. |
Prod: Bundler | π’ | π’ | -- | E.g. Minify assets, etc. Both are enabled by default. When RollDown (Rust) is ready in 2024, Svelte will be able to switch from Rollup+ESbuild to RollDown for even faster production builds. |
Prod: Auto code splitting, per route | π’ | π’ | -- | I.e. Auto code split JS & CSS per route & bundle appropriately. |
Prod: Build adapters for different hosts | π’ | β | SvelteKit | SvelteKit provides easy portability to many hosts. NextJS works best with Vercel. |
KB size: Hello World | π’ 46.3 (25.6 gzip) with CSR* π’ 2.9 (3.3 gzip) without CSR (1.8kb of this is the favicon; shows as bigger with gzip in Chrome) |
β 336.3 (131.3 gzip) (includes a 9.7kb favicon π)* | SvelteKit | - *CSR is "client side router". - SvelteKit updated Aug 25, 2023 using SvelteKit 1.23 & Svelte 4. - NextJS updated Aug 25, 2023 using App Router, NextJS 13.4.19, & React 18.2.0. - Both tests return HTML of <p>hello world</p> and exclude CSS. |
KB size: "Real World" app | too out of date | too out of date | -- | Out of date; PR welcome. *Mar 13, 2021 https://realworld.svelte.dev/, https://svelte.dev/blog/sapper-towards-the-ideal-web-app-framework |
Rendering: SSR, per route | π’ | π’ | -- | I.e. Server-side rendered at run time. |
Rendering: Streaming | π’ | π’ | -- | I.e. Server sends HTTP stream as it rendered on the server, rather than waiting for full rendering to complete before sending the response. |
Rendering: Static, per route | π’ | π’ | -- | I.e. Static HTML generated at build time. |
Rendering: Incremental Static Regeneration, per route | π’ on non-edge Vercel | π’ on non-edge Vercel | -- | Static 'on demand' in productionβi.e. first request dynamic, then cached as static. For other runtimes (like Edge on Vercel & Cloudflare), consider setting your route's cache-control header to use stale-while-revalidate for some similar benefits. |
Rendering: "Partial Prerendering" | β | π’π§* | NextJS | *"experimental", in NextJS v14 or newer. Allows static prerendring of a page + streaming dynamic areas, like user auth buttons in a header, shopping cart status, etc. |
Headers: s-max-age & max-age, per route | π’ | π’ | -- | |
Routes: File-based routing | π’ | π’ | -- | For simplicity. Other routing utilities should be included. |
Routes: "SPA mode" | π’ | π’ | -- | SSR for initial page load, then client-side routing for subsequent pages. |
Routes: Pre-fetch JS/CSS on link hover | π’ | π’ next/link | SvelteKit | By default in SvelteKit, can be overridden or removed. Svelte also offers a preloadCode() and prefetchData() to preload all or some routes specified via regex--powerful! NextJS requires using their link component; see docs. |
Built-in: Metadata | π’ | π’ next/head | -- | Place within <svelte:head>...</svelte:head> . |
Built-in: State management | π’ svelte/store | π’ useState | SvelteKit | Ideal is one, easy, built-in way. React has useState , Zustand, & others. Svelte4 uses reactive vars and stores. Svelte5 brings Runes (signals) for an even better DX, better state updating performance than React (due to being signal based), and the ability to use reactivity inside template files (e.g. .svelte ) and supporting files (e.g. .svelte.ts ), enabling new ways to refactor and abstract your code. Svelte continues to win on state management. |
Built-in: Animations | π’ svelte/animate | β | SvelteKit | 3rd-party options exist for React, but they're not as easy to use. FramerMotion is popular for React. Motion One is a also great library (small & fast) and works with any UI framework. |
Built-in: Image optimizations | π’ enhanced:img (beta) | π’ next/image | -- | Build-time image optimizations (conversion to AVIF or WEBP), creation of picture element with fallback to JPEG or PNG, resizing, adding width & height automatically, add file name hash for caching, etc. Hosted services exist as well if you prefer to do this at runtime (Cloudflare Images, Cloudinary, Gumlet, etc) |
Built-in: Forms | π’ Form actions & use:enhance (works with or without JS) or Formsnap (built on superforms) or Superforms |
π’ NextJS 13 Form and Server actions (works with or without JS, if built properly) | -- | Svelte has built-in form support with a progressive enhancement that works even without JS; they're very clean because validation rules are defined once and used for both client & server side. Formik (for React) is clean but requires JS and duplication of validation rules on the server side; similar to Felte (for React, SvelteKit, & Vue). |
Auth | π’ Auth.js or Lucia | π’ Auth.js or Lucia | -- | Auth.js (formely NextAuth.js) is defacto standard for NextJS; easy to use; email, social, &/or one-click link. It supports SvelteKit too. Original announcement. However, Lucia is very popular in the SvelteKit community. - thecopenhagenbook.com (free by the author of Lucia) may be helpful to learn how to set up Auth, for either framework. |
OG Image Generation | π’β @ethercorps/sveltekit-og* | π’ @vercel/og | NextJS | @ethercorps/sveltekit-og is based on Satori, which @vercel/og is also based on. *β on @ethercorps/sveltekit-og 's because not working on certain hosts like Cloudflare Pages. Credit to Vercel for creating Satori. Both include TailwindCSS support. Opportunity for someone to contribute an OG lib for SvelteKit! |
Sitemap | π’ Super Sitemap | π’ next-sitemap | -- | Super Sitemap wins on ease of use and being up to date expected conventions for sitemap, but both get the job done. Disclosure: I'm the author of Super Sitemap. Github issue for official sitemap.xml support in SvelteKit. |
Data fetching | π’ TanStack Query π’ SSWR π’ tRPC |
π’ TanStack Query π’ SWR π’ tRPC |
-- | Easy fetch/isLoading/errors/caching. SvelteKit provides automatic type safety (see note below the code sample) for data returned from load functions thanks to its autogenerated $types module, with no work on the dev's part. |
Tailwind CSS compatible | π’ (or via svelte-add) | π’ | NextJS b/c built in. Both are easy. | For NextJS, just check Yes for the TailwindCSS option when creating your NextJS app using create-next-app.Tailwind v4 will make set up even easier. |
UI Component Libs - Styled | - π’ Shadcn Svelte (unofficial)* - π’ Flowbite Svelte - π’ Skeleton UI - π’ Carbon Components Svelte |
- π’ Shadcn UI** - π’ Tailwind UI - π’ MUI - π’ Ant Design - π’ Mantine UI - π’ Chakra UI - π’ Flowbite React |
NextJS | - *Built on BitsUI (similar to RadixUI), which itself is built on MeltUI - **Built on RadixUI. |
UI Component Libs - Unstyled | - π’ Bits UI* - π’ Melt UI** - π’π§ svelte-headlessui (unofficial; issues for official support: 1, 2) |
- π’ Radix UI - π’ Headless UI - π’ React Aria |
NextJS | Un-styled UI components (dropdown, slider, toggle, etc). -*Built on MeltUI, to provide a more familiar component interface. - **Melt UI is the successor to radix-svelte. |
Docs | 10/10 | 10/10 | -- | |
Component Directory | sveltesociety.dev/components (add yours) | -- | ||
Dev Retention (proxy for enjoyment; Svelte vs React) | 90% | 83% | Svelte | *Source: State of JS 2022 Front-end frameworks 'Retention' |
Philosophy | Tenets | ? | n/a | "People use Svelte because they like Svelte. They like it because it aligns with their aesthetic sensibilities. Instead of striving to be the fastest or smallest or whateverest, we explicitly aim to be the framework with the best vibes. ... We're not trying to be the most popular framework, we're trying to be the best framework." π€ |
The following are low-priority framework features because they can be enabled easily via hosting providers or other common tools (e.g. analytics), or other best practices have emerged like using utility-based style frameworks.
Svelte Kit | NextJS | Winner | Notes | |
---|---|---|---|---|
Built-in: CSS scoping | π’ | π’ | SvelteKit | Svelte's is automatic. NextJS' is via CSS modules or CSS in JSX (not as clean). Irrelevant if you use TailwindCSS. Move to "low priority" b/c it's now standard to use a utility-based style framework like TailwindCSS or UnoCSS for composability & sharing of components. |
Prod: HTTP Early Hints response of JS/CSS** | β | β | Neither | **Not super relevant as a framework feature anymore because easily enabled via some hosting platform providers. Replaces HTTP2 Server Push. Send two responses: 1.) a 103 response status with headers listing resources to preload & preconnect; 2.) a standard 200 response status or similar. (Cloudflare can do this for sites automatically.) |
Web vitals reporting** | β | π’ | NextJS | **Not super relevant as a framework feature anymore because easily added via analytics snippet now or via some hosting platform providers. Cloudlfare Site Analytics offers Core Web Vitals tracking with zero configuration; it's part of their JS snippet. Vercel also offers it if using NextJS or NuxtJS & has a superb dashboard. |
CSS-only component libs (i.e. no JS) *categorically not recommended* |
- π’ DaisyUI -π’β Headless UI* |
π’ DaisyUI | -- | *Categorically not recommended b/c some components will require JavaScript and adding your own JS and achieving accessibility is hard; the better approach is to start with an accessible, JS-enabled UI component lib for your framework that comes with nice default styles and allows styling to your preference (e.g. Shadcn). - DaisyUI offers themes that can be one-off customized with TailwindCSS classes or altered using Tailwind's @apply directive. CSS-only components require the dev to add accessible interactions with JSβa lot of work.- **Headless UI is a paid product with official React and Vue support; can use as HTML & CSS with SvelteKit, but no JS. - Update: won't maintain this row anymore. |
Due to the wide ecosystem of Next JS, a framework built on top of Next JS Blitz JS is also an honorable mention. It comes with features that Next JS doesn't support natively like auth mechanism and more. Suitable for medium or large-size projects. And also, you can utilize your Next JS knowledge while using Blitz JS.