Home > Blog > tech

Svelte และ SvelteKit คืออะไร? Framework ที่เร็วที่สุด สำหรับ Frontend Developer 2026

svelte sveltekit guide
Svelte SvelteKit Guide 2026
2026-04-08 | tech | 3500 words

ในโลกของ Frontend Development ปี 2026 การเลือก Framework ที่เหมาะสมเป็นสิ่งสำคัญมาก React และ Vue ครองตลาดมานาน แต่มี Framework ตัวหนึ่งที่กำลังเติบโตอย่างรวดเร็วและได้รับความนิยมจากนักพัฒนาทั่วโลก นั่นคือ Svelte และ Meta-framework ของมันอย่าง SvelteKit ที่ถูกออกแบบมาให้เร็ว เขียนง่าย และมี Bundle Size เล็กที่สุดในบรรดา Framework ชั้นนำทั้งหมด

บทความนี้จะพาคุณเรียนรู้ Svelte ตั้งแต่แนวคิดพื้นฐานที่แตกต่างจาก Framework อื่น ไปจนถึงการสร้าง Full-stack Application ด้วย SvelteKit รวมถึงฟีเจอร์ล่าสุดอย่าง Svelte 5 Runes ที่จะเปลี่ยนวิธีการเขียน Reactive Code ไปตลอดกาล

Svelte คืออะไร? ทำไมจึงแตกต่าง

Svelte คือ Frontend Framework ที่สร้างโดย Rich Harris ในปี 2016 สิ่งที่ทำให้ Svelte แตกต่างจาก React หรือ Vue อย่างสิ้นเชิงคือ Svelte เป็น Compiler ไม่ใช่ Runtime Library

ใน React หรือ Vue เมื่อคุณเขียน Component เสร็จ Framework จะส่ง Runtime Library (Virtual DOM, Reconciler ฯลฯ) ไปกับ Code ของคุณด้วย ทำให้ Bundle Size ใหญ่ขึ้น และ Browser ต้องทำงานหนักขึ้นในการ Diff และ Patch DOM

แต่ Svelte ทำงานคนละแบบ มันจะ Compile Component ของคุณให้เป็น Vanilla JavaScript ตอน Build Time ผลลัพธ์คือ Code ที่ Manipulate DOM โดยตรง ไม่มี Virtual DOM ไม่มี Runtime Overhead ทำให้:

Svelte vs React vs Vue เปรียบเทียบแบบละเอียด

คุณสมบัติSvelteReactVue
ประเภทCompilerRuntime LibraryRuntime Library
Virtual DOMไม่มีมีมี
Bundle Size (min)~2 KB~42 KB~33 KB
ReactivityCompile-timeuseState/useEffectref/reactive
Syntaxใกล้ HTMLJSXSFC (.vue)
Learning Curveง่ายปานกลางปานกลาง
State ManagementStores (built-in)Redux/ZustandPinia/Vuex
Meta-frameworkSvelteKitNext.js/RemixNuxt
AnimationsBuilt-inThird-partyBuilt-in (basic)
Community Sizeกำลังโตใหญ่ที่สุดใหญ่
ข้อดีของ Svelte: ในการทดสอบ Benchmark ปี 2026 Svelte ยังคงเป็น Framework ที่มี Bundle Size เล็กที่สุดและ Startup Performance เร็วที่สุด โดยเฉพาะ Svelte 5 ที่ปรับปรุง Reactivity Engine ใหม่ทั้งหมด

เริ่มต้นกับ Svelte — การติดตั้ง

การเริ่มต้นโปรเจกต์ Svelte ใหม่ในปี 2026 แนะนำให้ใช้ SvelteKit เป็นหลัก เพราะเป็น Official Framework ที่รองรับทั้ง SPA, SSR และ Static Site Generation

# สร้างโปรเจกต์ SvelteKit ใหม่
npx sv create my-app
cd my-app

# เลือก template:
# - SvelteKit demo app
# - SvelteKit minimal
# - Svelte library

npm install
npm run dev

# เปิด browser ที่ http://localhost:5173

โครงสร้างโปรเจกต์ SvelteKit:

my-app/
├── src/
│   ├── lib/           # Shared components & utilities
│   │   └── index.js   # $lib alias
│   ├── routes/        # File-based routing
│   │   ├── +page.svelte      # หน้า Home
│   │   ├── +layout.svelte    # Layout wrapper
│   │   └── about/
│   │       └── +page.svelte  # /about page
│   ├── app.html       # HTML template
│   └── app.css        # Global styles
├── static/            # Static assets
├── svelte.config.js   # SvelteKit config
├── vite.config.js     # Vite config
└── package.json

Svelte Component พื้นฐาน

Svelte Component เขียนในไฟล์ .svelte ซึ่งประกอบด้วย 3 ส่วน: Script, Markup และ Style เหมือนกับ HTML ปกติ

<!-- Counter.svelte -->
<script>
  let count = 0;

  function increment() {
    count += 1;
  }

  function decrement() {
    count -= 1;
  }

  function reset() {
    count = 0;
  }
</script>

<div class="counter">
  <h2>Counter: {count}</h2>
  <button on:click={decrement}>-</button>
  <button on:click={reset}>Reset</button>
  <button on:click={increment}>+</button>
</div>

<style>
  .counter {
    text-align: center;
    padding: 20px;
  }
  button {
    margin: 0 8px;
    padding: 8px 16px;
    font-size: 1.2em;
    border-radius: 4px;
    cursor: pointer;
  }
</style>

สังเกตว่า Svelte ไม่ต้องใช้ useState หรือ ref แค่ประกาศตัวแปรธรรมดา แล้ว Svelte Compiler จะทำให้มันเป็น Reactive โดยอัตโนมัติ การ Assign ค่าใหม่ให้ตัวแปร (count += 1) จะ Trigger การ Update UI ทันที

Reactivity ใน Svelte — หัวใจของ Framework

Reactivity คือระบบที่ทำให้ UI อัพเดตตาม Data อัตโนมัติ Svelte มีระบบ Reactivity ที่เรียบง่ายแต่ทรงพลังมาก

Reactive Declarations ($:)

ใช้ $: เพื่อสร้าง Derived Values ที่คำนวณใหม่อัตโนมัติเมื่อ Dependencies เปลี่ยน:

<script>
  let width = 10;
  let height = 5;

  // Reactive declaration — คำนวณใหม่เมื่อ width หรือ height เปลี่ยน
  $: area = width * height;
  $: perimeter = 2 * (width + height);

  // Reactive statement — รันทุกครั้งที่ค่าเปลี่ยน
  $: if (area > 100) {
    console.log('Area exceeded 100!');
  }

  $: {
    console.log(`Width: ${width}, Height: ${height}`);
    console.log(`Area: ${area}, Perimeter: ${perimeter}`);
  }
</script>

<input type="range" bind:value={width} min="1" max="20">
<input type="range" bind:value={height} min="1" max="20">
<p>Area: {area} | Perimeter: {perimeter}</p>
Svelte Reactivity Rule: ใน Svelte 4 การ Update Array หรือ Object ต้องทำผ่าน Assignment เท่านั้น เช่น arr = [...arr, newItem] การ Push ไม่ Trigger Update เพราะ Reference ไม่เปลี่ยน ใน Svelte 5 ปัญหานี้ถูกแก้ด้วย Runes

Two-way Binding

<script>
  let name = '';
  let email = '';
  let agreed = false;
  let color = '#ff0000';
  let volume = 50;
  let flavor = 'vanilla';
  let sizes = [];
</script>

<!-- Text input -->
<input type="text" bind:value={name} placeholder="Name">
<input type="email" bind:value={email} placeholder="Email">

<!-- Checkbox -->
<label>
  <input type="checkbox" bind:checked={agreed}>
  I agree to terms
</label>

<!-- Range -->
<input type="range" bind:value={volume} min="0" max="100">

<!-- Select -->
<select bind:value={flavor}>
  <option value="vanilla">Vanilla</option>
  <option value="chocolate">Chocolate</option>
  <option value="strawberry">Strawberry</option>
</select>

<!-- Multiple checkbox (group) -->
<label><input type="checkbox" bind:group={sizes} value="S"> S</label>
<label><input type="checkbox" bind:group={sizes} value="M"> M</label>
<label><input type="checkbox" bind:group={sizes} value="L"> L</label>

Components — Props, Events และ Slots

Props (รับข้อมูลจาก Parent)

<!-- Card.svelte -->
<script>
  export let title;
  export let description = 'No description';  // default value
  export let variant = 'default';              // default value
</script>

<div class="card {variant}">
  <h3>{title}</h3>
  <p>{description}</p>
</div>

<!-- การใช้งาน -->
<Card title="My Card" description="Card content" variant="primary" />
<Card title="Simple Card" />

Events (ส่ง Event ไป Parent)

<!-- SearchBar.svelte -->
<script>
  import { createEventDispatcher } from 'svelte';
  const dispatch = createEventDispatcher();

  let query = '';

  function handleSearch() {
    dispatch('search', { query });
  }

  function handleClear() {
    query = '';
    dispatch('clear');
  }
</script>

<div class="search-bar">
  <input bind:value={query} on:keydown={(e) => e.key === 'Enter' && handleSearch()}>
  <button on:click={handleSearch}>Search</button>
  <button on:click={handleClear}>Clear</button>
</div>

<!-- Parent ใช้งาน -->
<SearchBar on:search={(e) => console.log(e.detail.query)} on:clear={() => console.log('cleared')} />

Slots (Content Projection)

<!-- Modal.svelte -->
<script>
  export let show = false;
  export let title = 'Modal';
</script>

{#if show}
<div class="modal-backdrop" on:click={() => show = false}>
  <div class="modal" on:click|stopPropagation>
    <header>
      <slot name="header">
        <h2>{title}</h2>
      </slot>
    </header>
    <main>
      <slot>
        <p>Default content</p>
      </slot>
    </main>
    <footer>
      <slot name="footer">
        <button on:click={() => show = false}>Close</button>
      </slot>
    </footer>
  </div>
</div>
{/if}

<!-- การใช้งาน -->
<Modal bind:show={showModal}>
  <h2 slot="header">Custom Title</h2>
  <p>This is the modal body content</p>
  <div slot="footer">
    <button on:click={() => showModal = false}>Cancel</button>
    <button on:click={save}>Save</button>
  </div>
</Modal>

Svelte Stores — State Management ในตัว

Svelte มีระบบ Store ในตัวสำหรับจัดการ State ที่แชร์ข้าม Components โดยไม่ต้องติดตั้ง Library เพิ่ม

Writable Store

// stores.js
import { writable } from 'svelte/store';

// สร้าง Store
export const count = writable(0);
export const user = writable(null);
export const theme = writable('light');

// Custom store with methods
function createTodoStore() {
  const { subscribe, set, update } = writable([]);

  return {
    subscribe,
    add: (text) => update(todos => [...todos, {
      id: Date.now(),
      text,
      done: false
    }]),
    toggle: (id) => update(todos =>
      todos.map(t => t.id === id ? { ...t, done: !t.done } : t)
    ),
    remove: (id) => update(todos =>
      todos.filter(t => t.id !== id)
    ),
    clear: () => set([])
  };
}

export const todos = createTodoStore();

ใช้ Store ใน Component

<script>
  import { count, todos } from './stores.js';

  // Auto-subscription ด้วย $ prefix
  // ไม่ต้อง subscribe/unsubscribe เอง!
</script>

<p>Count: {$count}</p>
<button on:click={() => $count += 1}>+1</button>
<button on:click={() => count.set(0)}>Reset</button>

<h3>Todos ({$todos.length})</h3>
{#each $todos as todo (todo.id)}
  <div>
    <input type="checkbox" checked={todo.done} on:change={() => todos.toggle(todo.id)}>
    <span class:done={todo.done}>{todo.text}</span>
    <button on:click={() => todos.remove(todo.id)}>X</button>
  </div>
{/each}

Readable และ Derived Stores

import { readable, derived } from 'svelte/store';

// Readable store — ค่าที่เปลี่ยนจากภายนอก
export const time = readable(new Date(), function start(set) {
  const interval = setInterval(() => set(new Date()), 1000);
  return function stop() { clearInterval(interval); };
});

// Derived store — คำนวณจาก Store อื่น
export const elapsed = derived(time, ($time) =>
  Math.round(($time - startTime) / 1000)
);

// Derived จากหลาย Stores
export const fullName = derived(
  [firstName, lastName],
  ([$firstName, $lastName]) => `${$firstName} ${$lastName}`
);

// Derived จาก todos — นับเฉพาะที่ยังไม่เสร็จ
export const pendingCount = derived(todos, ($todos) =>
  $todos.filter(t => !t.done).length
);

Lifecycle ของ Svelte Component

<script>
  import { onMount, onDestroy, beforeUpdate, afterUpdate, tick } from 'svelte';

  // onMount — หลัง Component ถูก Render ครั้งแรก
  onMount(() => {
    console.log('Component mounted');
    // เหมาะสำหรับ fetch data, setup event listeners
    const data = await fetch('/api/data').then(r => r.json());

    // Return cleanup function (optional)
    return () => {
      console.log('Cleanup on destroy');
    };
  });

  // onDestroy — ก่อน Component ถูกลบ
  onDestroy(() => {
    console.log('Component destroyed');
  });

  // beforeUpdate — ก่อน DOM update
  beforeUpdate(() => {
    console.log('About to update DOM');
  });

  // afterUpdate — หลัง DOM update
  afterUpdate(() => {
    console.log('DOM updated');
  });

  // tick() — รอจนกว่า DOM จะ update เสร็จ
  async function handleClick() {
    count += 1;
    await tick(); // รอ DOM update
    // ตอนนี้ DOM อัพเดตแล้ว
  }
</script>

Transitions และ Animations

Svelte มีระบบ Transition และ Animation ในตัวที่ทรงพลังมาก ไม่ต้องติดตั้ง Library เพิ่ม:

<script>
  import { fade, fly, slide, scale, blur, draw } from 'svelte/transition';
  import { flip } from 'svelte/animate';
  import { quintOut } from 'svelte/easing';

  let visible = true;
  let items = [1, 2, 3, 4, 5];
</script>

<!-- Basic transition -->
<button on:click={() => visible = !visible}>Toggle</button>

{#if visible}
  <div transition:fade>Fades in and out</div>
  <div transition:fly={{ y: 200, duration: 500 }}>Flies in from below</div>
  <div transition:slide>Slides in</div>
  <div transition:scale={{ start: 0.5 }}>Scales in</div>
  <div transition:blur={{ amount: 10 }}>Blurs in</div>
{/if}

<!-- in/out แยกกัน -->
{#if visible}
  <div in:fly={{ x: -200 }} out:fade>
    Flies in from left, fades out
  </div>
{/if}

<!-- Animate list items -->
{#each items as item (item)}
  <div animate:flip={{ duration: 300 }}>
    Item {item}
  </div>
{/each}
Performance Tip: Svelte Transitions ใช้ CSS Animations ภายใน ทำให้ทำงานบน GPU และไม่ Block Main Thread ต่างจาก Library อื่นที่ใช้ JavaScript Animation

SvelteKit — Full-stack Framework

SvelteKit คือ Official Meta-framework ของ Svelte (เทียบได้กับ Next.js สำหรับ React หรือ Nuxt สำหรับ Vue) มีฟีเจอร์ครบครันสำหรับสร้าง Full-stack Web Application

File-based Routing

SvelteKit ใช้ระบบ File-based Routing ที่โครงสร้างโฟลเดอร์ใน src/routes กำหนด URL:

src/routes/
├── +page.svelte              # / (หน้าแรก)
├── +layout.svelte            # Layout สำหรับทุกหน้า
├── +error.svelte             # Error page
├── about/
│   └── +page.svelte          # /about
├── blog/
│   ├── +page.svelte          # /blog
│   ├── +page.server.js       # Server load function
│   └── [slug]/
│       ├── +page.svelte      # /blog/:slug (dynamic route)
│       └── +page.server.js   # Load data for each post
├── api/
│   └── users/
│       └── +server.js        # API endpoint: GET/POST /api/users
└── (auth)/                   # Route group (ไม่ส่งผลต่อ URL)
    ├── login/
    │   └── +page.svelte      # /login
    └── register/
        └── +page.svelte      # /register

+page.svelte — หน้าเว็บ

<!-- src/routes/blog/+page.svelte -->
<script>
  export let data;  // ข้อมูลจาก load function
</script>

<svelte:head>
  <title>Blog Posts</title>
  <meta name="description" content="Our latest blog posts">
</svelte:head>

<h1>Blog</h1>
{#each data.posts as post}
  <article>
    <h2><a href="/blog/{post.slug}">{post.title}</a></h2>
    <p>{post.excerpt}</p>
    <time>{post.date}</time>
  </article>
{/each}

+page.server.js — Server Load Function

// src/routes/blog/+page.server.js
import { error } from '@sveltejs/kit';

export async function load({ fetch, params, url }) {
  const page = url.searchParams.get('page') || 1;
  const response = await fetch(`/api/posts?page=${page}`);

  if (!response.ok) {
    throw error(404, 'Posts not found');
  }

  const posts = await response.json();

  return {
    posts,
    page: Number(page),
    totalPages: posts.totalPages
  };
}

// src/routes/blog/[slug]/+page.server.js
export async function load({ params }) {
  const { slug } = params;
  const post = await getPostBySlug(slug);

  if (!post) {
    throw error(404, 'Post not found');
  }

  return { post };
}

+layout.svelte — Layout ที่ครอบทุกหน้า

<!-- src/routes/+layout.svelte -->
<script>
  import '../app.css';
  export let data;
</script>

<nav>
  <a href="/">Home</a>
  <a href="/blog">Blog</a>
  <a href="/about">About</a>
  {#if data.user}
    <span>{data.user.name}</span>
  {:else}
    <a href="/login">Login</a>
  {/if}
</nav>

<main>
  <slot />
</main>

<footer>
  <p>Copyright 2026</p>
</footer>

+server.js — API Routes

// src/routes/api/users/+server.js
import { json, error } from '@sveltejs/kit';

export async function GET({ url }) {
  const page = url.searchParams.get('page') || 1;
  const users = await db.getUsers(page);
  return json(users);
}

export async function POST({ request }) {
  const body = await request.json();

  if (!body.name || !body.email) {
    throw error(400, 'Name and email are required');
  }

  const user = await db.createUser(body);
  return json(user, { status: 201 });
}

export async function PUT({ request }) {
  const body = await request.json();
  const user = await db.updateUser(body.id, body);
  return json(user);
}

export async function DELETE({ url }) {
  const id = url.searchParams.get('id');
  await db.deleteUser(id);
  return new Response(null, { status: 204 });
}

Form Actions — จัดการ Form แบบ Progressive Enhancement

// src/routes/login/+page.server.js
import { fail, redirect } from '@sveltejs/kit';

export const actions = {
  login: async ({ request, cookies }) => {
    const data = await request.formData();
    const email = data.get('email');
    const password = data.get('password');

    if (!email || !password) {
      return fail(400, { email, message: 'All fields are required' });
    }

    const user = await authenticateUser(email, password);
    if (!user) {
      return fail(401, { email, message: 'Invalid credentials' });
    }

    cookies.set('session', user.token, {
      path: '/',
      httpOnly: true,
      secure: true,
      sameSite: 'strict',
      maxAge: 60 * 60 * 24 * 7 // 7 days
    });

    throw redirect(303, '/dashboard');
  },

  register: async ({ request }) => {
    // Handle registration
  }
};

<!-- src/routes/login/+page.svelte -->
<script>
  import { enhance } from '$app/forms';
  export let form;  // ข้อมูลจาก fail()
</script>

<form method="POST" action="?/login" use:enhance>
  {#if form?.message}
    <p class="error">{form.message}</p>
  {/if}
  <input name="email" type="email" value={form?.email ?? ''} required>
  <input name="password" type="password" required>
  <button type="submit">Login</button>
</form>
Progressive Enhancement: Form Actions ของ SvelteKit ทำงานได้แม้ปิด JavaScript เพราะใช้ HTML Form ปกติ แล้วใช้ use:enhance เพื่อเพิ่ม UX ดีขึ้นเมื่อมี JS

Server-Side Rendering (SSR) ใน SvelteKit

SvelteKit รองรับ Rendering หลายแบบในแต่ละหน้า:

// src/routes/+page.js — ทั้ง Server และ Client
export const prerender = true;     // Static Site Generation
export const ssr = true;           // Server-Side Render (default)
export const csr = true;           // Client-Side Render (default)

// ตัวเลือก Rendering:
// 1. SSR (default) — Render บน Server ทุก Request
// 2. Prerender — Render ตอน Build (Static HTML)
// 3. CSR only — Render บน Client เท่านั้น
// 4. SSR + CSR — Render Server ก่อน แล้ว Hydrate บน Client

// ปิด SSR สำหรับ SPA-only page
export const ssr = false;

// Prerender เฉพาะบางหน้า
export const prerender = true;

SvelteKit Adapters — Deploy ทุกที่

SvelteKit ใช้ระบบ Adapter เพื่อ Build ให้เหมาะกับ Platform ต่างๆ:

// svelte.config.js
import adapter from '@sveltejs/adapter-auto';  // เลือกให้อัตโนมัติ

export default {
  kit: {
    adapter: adapter()
  }
};

// Adapter ที่มีให้เลือก:
// @sveltejs/adapter-auto     — ตรวจจับ Platform อัตโนมัติ
// @sveltejs/adapter-node     — Node.js Server
// @sveltejs/adapter-static   — Static Site (HTML/CSS/JS)
// @sveltejs/adapter-vercel   — Vercel
// @sveltejs/adapter-cloudflare — Cloudflare Pages
// @sveltejs/adapter-netlify  — Netlify
# ติดตั้ง Adapter
npm i -D @sveltejs/adapter-node

# Build
npm run build

# Preview
npm run preview

# Deploy (ตัวอย่าง Node.js)
node build/index.js

SvelteKit vs Next.js เปรียบเทียบ

คุณสมบัติSvelteKitNext.js
Base FrameworkSvelte (Compiler)React (Runtime)
Bundle Sizeเล็กกว่ามากใหญ่กว่า (React Runtime)
RoutingFile-based (+page.svelte)File-based (page.tsx)
SSR/SSGทั้งคู่ทั้งคู่
API Routes+server.jsroute.ts
Form HandlingForm Actions (built-in)Server Actions
State ManagementStores (built-in)ต้องเลือก Library
AnimationsBuilt-in transitionsต้องใช้ Framer Motion
Learning Curveง่ายกว่าซับซ้อนกว่า
Communityเล็กกว่าแต่โตเร็วใหญ่มาก
Job Marketน้อยกว่ามากกว่า

Svelte 5 Runes — อนาคตของ Svelte

Svelte 5 เปิดตัว Runes ระบบ Reactivity ใหม่ที่ทำให้ Svelte ทรงพลังและยืดหยุ่นมากขึ้น เป็นการเปลี่ยนแปลงครั้งใหญ่ที่สุดของ Svelte:

$state — แทนที่ let

<script>
  // Svelte 4 (เดิม)
  let count = 0;

  // Svelte 5 (Runes)
  let count = $state(0);
  let user = $state({ name: 'John', age: 30 });
  let items = $state([1, 2, 3]);

  // Deep reactivity — ใน Svelte 5 push() ทำงานได้แล้ว!
  function addItem() {
    items.push(items.length + 1);  // Reactive ใน Svelte 5
  }
</script>

$derived — แทนที่ $:

<script>
  let width = $state(10);
  let height = $state(5);

  // Svelte 4
  // $: area = width * height;

  // Svelte 5
  let area = $derived(width * height);
  let perimeter = $derived(2 * (width + height));
  let isLarge = $derived(area > 100);

  // Complex derived
  let summary = $derived.by(() => {
    if (area > 100) return 'Large';
    if (area > 50) return 'Medium';
    return 'Small';
  });
</script>

$effect — แทนที่ $: statements

<script>
  let count = $state(0);

  // Svelte 5 effect — รันเมื่อ dependencies เปลี่ยน
  $effect(() => {
    console.log(`Count changed to ${count}`);
    document.title = `Count: ${count}`;

    // Cleanup function
    return () => {
      console.log('Cleaning up previous effect');
    };
  });

  // $effect.pre — รันก่อน DOM update
  $effect.pre(() => {
    console.log('Before DOM update');
  });
</script>

$props — แทนที่ export let

<script>
  // Svelte 4
  // export let title;
  // export let description = '';

  // Svelte 5
  let { title, description = '', ...rest } = $props();
</script>

<div {...rest}>
  <h2>{title}</h2>
  <p>{description}</p>
</div>
Svelte 5 Migration: Svelte 5 ยังรองรับ Syntax เก่า (let, $:, export let) ดังนั้นคุณสามารถ Migrate ทีละ Component ได้ ไม่จำเป็นต้องเปลี่ยนทั้งโปรเจกต์พร้อมกัน

Component Libraries สำหรับ Svelte

ในปี 2026 มี Component Library ที่ดีหลายตัวสำหรับ Svelte:

Skeleton UI

# ติดตั้ง
npx sv create my-app
# เลือก Skeleton ใน setup wizard

# หรือเพิ่มเข้าโปรเจกต์เดิม
npm i -D @skeletonlabs/skeleton @skeletonlabs/tw-plugin

shadcn-svelte

# ติดตั้ง
npx shadcn-svelte init

# เพิ่ม Components
npx shadcn-svelte add button
npx shadcn-svelte add card
npx shadcn-svelte add dialog

# ใช้งาน
<script>
  import { Button } from '$lib/components/ui/button';
  import * as Card from '$lib/components/ui/card';
</script>

<Button variant="outline">Click me</Button>

<Card.Root>
  <Card.Header>
    <Card.Title>Title</Card.Title>
  </Card.Header>
  <Card.Content>Content here</Card.Content>
</Card.Root>

Flowbite Svelte

npm i -D flowbite-svelte flowbite

# มี Components มากกว่า 50 ตัว:
# Alert, Badge, Button, Card, Dropdown, Modal, Navbar,
# Pagination, Table, Tabs, Toast, Tooltip, etc.

Testing Svelte Applications

Unit Testing ด้วย Vitest

# ติดตั้ง
npm i -D vitest @testing-library/svelte @testing-library/jest-dom jsdom

// vite.config.js
import { defineConfig } from 'vite';
import { svelte } from '@sveltejs/vite-plugin-svelte';

export default defineConfig({
  plugins: [svelte({ hot: !process.env.VITEST })],
  test: {
    include: ['src/**/*.test.js'],
    environment: 'jsdom',
    globals: true
  }
});

// src/lib/Counter.test.js
import { render, fireEvent } from '@testing-library/svelte';
import { expect, test } from 'vitest';
import Counter from './Counter.svelte';

test('renders initial count', () => {
  const { getByText } = render(Counter);
  expect(getByText('Counter: 0')).toBeTruthy();
});

test('increments count on click', async () => {
  const { getByText } = render(Counter);
  const button = getByText('+');
  await fireEvent.click(button);
  expect(getByText('Counter: 1')).toBeTruthy();
});

E2E Testing ด้วย Playwright

# ติดตั้ง
npm i -D @playwright/test

// playwright.config.js
import { defineConfig } from '@playwright/test';

export default defineConfig({
  webServer: {
    command: 'npm run build && npm run preview',
    port: 4173
  },
  testDir: 'tests'
});

// tests/home.test.js
import { test, expect } from '@playwright/test';

test('homepage has correct title', async ({ page }) => {
  await page.goto('/');
  await expect(page).toHaveTitle(/My App/);
});

test('navigation works', async ({ page }) => {
  await page.goto('/');
  await page.click('a[href="/about"]');
  await expect(page.locator('h1')).toHaveText('About');
});

test('form submission works', async ({ page }) => {
  await page.goto('/login');
  await page.fill('input[name="email"]', 'test@test.com');
  await page.fill('input[name="password"]', 'password');
  await page.click('button[type="submit"]');
  await expect(page).toHaveURL('/dashboard');
});

Performance Benchmarks

จากการทดสอบ JavaScript Framework Benchmark ปี 2026:

MetricSvelte 5React 19Vue 3.5Solid
Create 1000 rows42ms68ms55ms39ms
Update every 10th18ms32ms24ms16ms
Swap rows21ms45ms28ms19ms
Remove row15ms28ms20ms14ms
Startup time12ms35ms25ms11ms
Memory (MB)2.14.83.22.0
Bundle (gzip)1.8 KB42 KB33 KB7 KB
สรุป Performance: Svelte 5 มี Performance ใกล้เคียง SolidJS (ซึ่งเร็วที่สุด) แต่มี Developer Experience ที่ดีกว่ามาก Bundle Size เล็กที่สุดในกลุ่ม Framework ยอดนิยม

เมื่อไหร่ควรเลือก Svelte

Svelte เหมาะกับโปรเจกต์ประเภทเหล่านี้:

Svelte อาจไม่เหมาะถ้า:

ตัวอย่างโปรเจกต์จริง — SvelteKit Blog

// svelte.config.js
import adapter from '@sveltejs/adapter-auto';
import { mdsvex } from 'mdsvex';

export default {
  extensions: ['.svelte', '.md'],
  preprocess: [mdsvex({ extensions: ['.md'] })],
  kit: {
    adapter: adapter()
  }
};

// src/routes/blog/[slug]/+page.server.js
export async function load({ params }) {
  try {
    const post = await import(`../../../content/${params.slug}.md`);
    return {
      content: post.default,
      meta: post.metadata
    };
  } catch (e) {
    throw error(404, 'Post not found');
  }
}

// src/routes/blog/[slug]/+page.svelte
<script>
  export let data;
</script>

<svelte:head>
  <title>{data.meta.title}</title>
</svelte:head>

<article>
  <h1>{data.meta.title}</h1>
  <time>{data.meta.date}</time>
  <svelte:component this={data.content} />
</article>

สรุป

Svelte และ SvelteKit เป็น Framework ที่เปลี่ยนวิธีคิดเกี่ยวกับ Frontend Development โดยพื้นฐาน แนวคิด Compiler-first ทำให้ได้ Bundle Size เล็ก Performance สูง และ Developer Experience ที่ยอดเยี่ยม Svelte 5 Runes ยกระดับ Reactivity ให้ทรงพลังยิ่งขึ้นพร้อมรักษาความเรียบง่ายที่เป็นเอกลักษณ์ของ Svelte

ในปี 2026 SvelteKit เป็นตัวเลือกที่ดีเยี่ยมสำหรับทั้ง Side Project และ Production Application ถ้าคุณเบื่อกับความซับซ้อนของ React หรือต้องการ Framework ที่เร็วและเขียนง่าย Svelte คือคำตอบที่ควรลอง เริ่มต้นวันนี้ด้วย npx sv create my-app แล้วคุณจะเข้าใจว่าทำไม Developer ทั่วโลกถึงหลงรัก Svelte


Back to Blog | iCafe Forex | SiamLanCard | Siam2R