はじめに
SvelteKitは「Web development, streamlined」を掲げるフルスタックWebフレームワークですね。
GitHubで20,100スター以上、202,000以上のプロジェクトで使われているという数字を見ると、その勢いがよくわかります。ReactユーザーにとってのNext.js、VueユーザーにとってのNuxtに相当する存在で、Svelteエコシステムの中核を担っています。
正直なところ、最初は「Svelteって流行ってるけど、結局Reactでいいんじゃないの」と思っていたんですよ。でも実際にSvelteKitでアプリを作ってみたら、なんというか「開発体験が違いすぎる」という感覚でした。
最新バージョンはv2.49.2で、635人以上のコントリビューターが活発に開発を続けています。
SvelteKitとは
SvelteKitは、Svelteを基盤としたフルスタックWebアプリケーションフレームワークです。クライアントとサーバーの相互作用を抽象化し、開発者がビジネスロジックに集中できる環境を提供してくれます。
特筆すべきは「退屈な部分を自動化してくれる」という点。ルーティング、ビルド最適化、データフェッチ...こういった定番の作業を、ベストプラクティスに沿って自動的に処理してくれる。これ、意外と時短になるんですよ。
特徴・メリット
1. Viteベースで圧倒的に速い開発体験
SvelteKitはViteをベースにしているので、開発サーバーの起動が一瞬です。Hot Module Replacementも高速で、コード変更がブラウザに即座に反映される。
30代になって思うのは、待ち時間って地味にストレスなんですよね。その点、SvelteKitの開発体験はかなり快適です。
2. 柔軟なレンダリング戦略
ページごとにレンダリング方法を選択できます。
- SSR(サーバーサイドレンダリング): 動的なコンテンツに最適
- CSR(クライアントサイドレンダリング): SPAライクな動作
- プリレンダリング(SSG): 静的サイト生成
同じプロジェクト内で混在できるので、「ブログページは静的に、ダッシュボードはSSRで」といった使い分けが簡単にできる。コスパ的にこれはかなり良いと思います。
3. プラットフォームを選ばないデプロイ
公式アダプターが充実していて、様々なプラットフォームにデプロイできます。
- @sveltejs/adapter-auto: 自動判定
- @sveltejs/adapter-vercel: Vercel
- @sveltejs/adapter-netlify: Netlify
- @sveltejs/adapter-cloudflare: Cloudflare
- @sveltejs/adapter-node: Node.jsサーバー
- @sveltejs/adapter-static: 静的サイト
個人的には、adapter-autoで自動判定してくれるのが楽ですね。
4. ファイルベースルーティング
src/routes/ディレクトリにファイルを置くだけでルーティングが設定されます。Next.jsのApp Routerに慣れている人なら、すぐに理解できるはず。
5. 組み込みの最適化機能
画像最適化、コード分割、プリロード...モダンなWeb開発に必要な最適化が最初から組み込まれています。サービスワーカーによるオフラインサポートも対応済み。
インストール方法
前提条件
Node.js 18.13以上が必要です。
新規プロジェクトの作成
公式が推奨しているのはこの方法です。
# npm
npx sv create my-app
# pnpm
pnpm create svelte@latest my-app
# yarn
yarn create svelte my-app
対話形式でテンプレートやTypeScriptの使用を選択できます。
cd my-app
npm install
npm run dev
これだけで開発サーバーが起動します。時短になる。
既存のSvelteプロジェクトに追加
npm install --save-dev @sveltejs/kit
基本的な使い方
プロジェクト構成
新規作成すると、こんな構成になります。
my-app/
├── src/
│ ├── routes/
│ │ ├── +page.svelte # ホームページ
│ │ ├── +layout.svelte # 共通レイアウト
│ │ └── about/
│ │ └── +page.svelte # /about ページ
│ ├── lib/
│ │ └── components/ # 共通コンポーネント
│ └── app.html # HTMLテンプレート
├── static/ # 静的アセット
├── svelte.config.js # Svelte設定
├── vite.config.js # Vite設定
└── package.json
ルーティングの仕組み
SvelteKitのルーティングは直感的です。
src/routes/+page.svelte → /
src/routes/about/+page.svelte → /about
src/routes/blog/+page.svelte → /blog
src/routes/blog/[slug]/+page.svelte → /blog/:slug(動的ルート)
ページコンポーネントの書き方
<!-- src/routes/+page.svelte -->
<script>
let count = 0;
function increment() {
count += 1;
}
</script>
<h1>Welcome to SvelteKit</h1>
<p>カウント: {count}</p>
<button on:click={increment}>+1</button>
<style>
h1 {
color: #ff3e00;
}
button {
padding: 0.5rem 1rem;
cursor: pointer;
}
</style>
見た感じ、普通のHTMLを書いているような感覚で書けますね。ReactのようにuseStateを呼んだり、classNameと書いたりする必要がない。これがSvelteの魅力です。
レイアウトの共有
+layout.svelteで共通レイアウトを定義できます。
<!-- src/routes/+layout.svelte -->
<script>
import Header from '$lib/components/Header.svelte';
import Footer from '$lib/components/Footer.svelte';
</script>
<Header />
<main>
<slot /> <!-- 子ページがここに入る -->
</main>
<Footer />
<style>
main {
max-width: 1200px;
margin: 0 auto;
padding: 1rem;
}
</style>
データの読み込み
+page.server.jsでサーバーサイドのデータ取得ができます。
// src/routes/blog/+page.server.js
export async function load() {
const response = await fetch('https://api.example.com/posts');
const posts = await response.json();
return {
posts
};
}
<!-- src/routes/blog/+page.svelte -->
<script>
export let data;
</script>
<h1>ブログ記事一覧</h1>
<ul>
{#each data.posts as post}
<li>
<a href="/blog/{post.slug}">{post.title}</a>
</li>
{/each}
</ul>
このload関数がNext.jsのgetServerSidePropsに相当する部分ですね。
フォームアクション
SvelteKitの特徴的な機能として、フォーム処理があります。
// src/routes/contact/+page.server.js
export const actions = {
default: async ({ request }) => {
const data = await request.formData();
const name = data.get('name');
const email = data.get('email');
// データベースに保存したり、メール送信したり
return { success: true };
}
};
<!-- src/routes/contact/+page.svelte -->
<script>
export let form;
</script>
{#if form?.success}
<p>送信完了しました!</p>
{:else}
<form method="POST">
<input type="text" name="name" placeholder="お名前" required />
<input type="email" name="email" placeholder="メールアドレス" required />
<button type="submit">送信</button>
</form>
{/if}
JavaScriptが無効でも動作する、プログレッシブエンハンスメントな設計になっています。
実践的なユースケース
静的サイト生成(SSG)
ブログやポートフォリオなら、静的サイト生成が最適です。
// svelte.config.js
import adapter from '@sveltejs/adapter-static';
export default {
kit: {
adapter: adapter({
pages: 'build',
assets: 'build',
fallback: null,
precompress: false
})
}
};
// src/routes/+layout.js
export const prerender = true;
これだけで全ページが静的HTMLとして出力されます。
APIエンドポイントの作成
+server.jsでREST APIを作成できます。
// src/routes/api/users/+server.js
import { json } from '@sveltejs/kit';
export async function GET() {
const users = await db.getUsers();
return json(users);
}
export async function POST({ request }) {
const data = await request.json();
const user = await db.createUser(data);
return json(user, { status: 201 });
}
フロントエンドとバックエンドを同じプロジェクトで管理できるのは、個人的にかなり楽だと思います。
環境変数の扱い
// .env
PUBLIC_API_URL=https://api.example.com
DATABASE_URL=postgres://...
PUBLIC_プレフィックスがついた変数はクライアントに公開、ついていない変数はサーバーのみで使用という明確なルールがあります。
import { PUBLIC_API_URL } from '$env/static/public';
import { DATABASE_URL } from '$env/static/private';
Next.jsとの比較
よく聞かれるのが「Next.jsとどっちがいいの?」という話。
| 観点 | SvelteKit | Next.js |
|---|---|---|
| ベース技術 | Svelte | React |
| バンドルサイズ | 小さい | 大きめ |
| 学習曲線 | 緩やか | React知識必要 |
| エコシステム | 成長中 | 成熟 |
| パフォーマンス | 優秀 | 良好 |
| 求人数 | 少なめ | 多い |
正直なところ、仕事で使うならReact/Next.jsの方が求人は多い。でも個人プロジェクトや、パフォーマンスを追求したいケースでは、SvelteKitの方が開発体験もバンドルサイズも優れていると感じます。
Svelteはコンパイル時に最適化されたJavaScriptを生成するので、ランタイムのオーバーヘッドがほぼない。これがパフォーマンスの秘密です。
まとめ
SvelteKitを使って感じた変化:
- 開発速度: 記述量が減って明らかに速くなった
- バンドルサイズ: Reactに比べて劇的に小さい
- 学習コスト: HTMLが書ければすぐ始められる
- 開発体験: Viteの恩恵で快適
- QOL: 確実に上がった
フルスタック開発を効率化したいなら、SvelteKitは有力な選択肢ですね。
特にパフォーマンスを重視するプロジェクト、個人開発、スタートアップなど、「重厚なエコシステムより軽快さを優先したい」ケースには最適だと思います。
ただし、チーム開発でReactエンジニアが多い環境や、既存のReactコンポーネント資産を活用したい場合は、Next.jsの方が現実的かもしれません。適材適所で使い分けるのが大事。