Show, don't claim
このページが送る JavaScript は 12 KB。
このサイトの動く部分すべて、風のアニメーション・コピーボタン・スクロール演出を合わせて、Preact 込みで gzip 後 12 KB です。島の無いページは 0 KB。参考までに、React と ReactDOM だけで gzip 後およそ 45 KB、あなたのコードを書く前にこれです。
このサイト自身の本番ビルドで実測(このサイトは Nowaki 製です)。Next や Astro との厳密な直接ベンチはロードマップにあります。
打鍵ごとに感じる速さ。
多くの JavaScript フレームワークは、起動・変換・再ビルドを JavaScript ツールチェーンの上で行います。Nowaki はそのパイプライン全体を Rust(oxc)で動かすので、JavaScript バンドラーが温まりきる前に dev サーバーは応答しています。
サンプルアプリで実測した dev サーバー起動。
oxc による変更ファイルの再変換。JS バンドラーのウォームアップなし。
本番出力: モジュールを1スコープへ連結、ツリーシェイク、content-hash、ソースマップ付き。
何もない状態から、Rust なしで動くアプリへ。
npm create nowaki@latest雛形作成
file-based の routes/ と islands/ を生成。CLI はプリビルドのバイナリなので、Rust を入れる必要はありません。
npm run dev開発
Rust の oxc パイプラインがオンデマンドで変換。島はハイドレートし、それ以外は HTML のまま。エラーは全画面オーバーレイで表示。
npm run build · start公開
scope-hoisting 済み・content-hash 付きの ESM と SSR モジュールを本番配信。あるいは静的に prerender して CDN へ。
ルートを書き、島を印し、フォームを受ける。
ルートは、サーバーでのみ走る任意の loader を持つコンポーネント。非 GET リクエストはルートの action が処理します。ブラウザでハイドレートするのは islands/ のものだけです。
loader 付きルート
// routes/blog/[slug].tsx
import Comments from "../../islands/Comments.tsx";
// runs on the server only
export const loader = async ({ params }) => ({
post: await db.post(params.slug),
});
export default function Post({ data }) {
return (
<article>
<h1>{data.post.title}</h1>
<Comments postId={data.post.id} /> // only this hydrates
</article>
);
}action 付きフォーム
// routes/guestbook.tsx
export const loader = (ctx) => ({ entries: read(ctx) });
// a non-GET request runs the action
export async function action(ctx) {
const form = await ctx.formData();
ctx.setCookie("guestbook", add(form.get("msg")));
return ctx.redirect("/guestbook"); // PRG
}ファイル規約
routes/_layout.tsx共有レイアウト、ディレクトリ単位でネストroutes/_middleware.tsルート前に実行。認証・リダイレクト・ヘッダroutes/blog/[slug].tsx動的ルート + server loaderroutes/api/posts.tsGET / POST ハンドラ、streaming Responseroutes/_404.tsx · _500.tsx未一致ページとエラーページislands/Counter.tsxブラウザでハイドレート。それ以外はしない。Next・Astro と並べて、正直に。
どのアイデアも単体では新しくありません。Nowaki の賭けはその組み合わせです。誇張なしで、実際にどこが違うかを示します。
| . | Nowaki | Next.js | Astro |
|---|---|---|---|
| ツールチェーン | Rust (oxc) を自作 | Turbopack (SWC) | Vite → Rolldown |
| デフォルトの JavaScript | ゼロ、島だけ | React を送り hydrate | ゼロ、島だけ |
| フルスタックなアプリ DX | routing・loader・action・middleware・API | あり、成熟 | 成長中・コンテンツ寄り |
| ツールチェーンの言語なしで入る | npm、Rust 不要 | npm | npm |
| 成熟度 | alpha | 成熟・巨大なエコシステム | 成熟 |
Next と Astro は成熟し実戦で揉まれています。Nowaki は alpha です。この表の主旨はアーキテクチャであって、勝敗表ではありません。
どんなアプリに向くか。
Nowaki が向くのは、コンテンツ主体だが動的なアプリです。認証付きのマーケ、対話ウィジェット入りのドキュメント、本物のサーバーデータを持つ管理画面、EC。本文とサーバーデータが大半なのに、全 hydrate のフレームワークだと1ページに数百 KB の JavaScript を送ってしまう、その層です。
向いている
- Next.js 風にアプリを書くが、各ページの大半は静的コンテンツとサーバーデータ。
- フォーム・認証・動的ルートが欲しいが、全ページにクライアントランタイムの代金は払いたくない。
- Remix 風の loader / action モデルが好きで、それを使う所にだけ JS を送りたい。
まだ得意でない
- ほぼ全部が状態を持つ、全面インタラクティブな SPA。島はそこでは窮屈で、全 hydrate や RSC の方が合います。
- 今日の本番クリティカルな用途。Nowaki は alpha で、API はまだ動きます。
静的サイトジェネレータではない、本物のフレームワーク。
Next.js / Remix 系譜の動的なアプリ向けに作られ、実際にプロダクトを載せられる部品が揃っています。
フルスタックなルーティング
file-based の routes/ に、ネスト可能な _layout・_middleware・server loader・フォーム用の action、そしてメソッド分岐と streaming に対応した api/ ハンドラ。
デフォルトで島・JS ゼロ
ページはサーバーで HTML に描画。islands/ 配下のコンポーネントだけが配信・ハイドレートされ、ページが払うのは実際に使う分だけ。
Rust ツールチェーン (oxc)
パース・変換・解決・バンドル・minify・スコープホイスティングが Rust で動作。高速なコールドスタート、数ミリ秒の再ビルド、再起動をまたぐ永続ディスクキャッシュ。
npm で入る、Rust 不要
CLI は npm の optionalDependencies でプリビルドのネイティブバイナリとして配布。cargo もツールチェーンも postinstall も不要。
島間 SPA ルーター
島のあるページ間の遷移はクライアント側で即時、prefetch とスクロール復元つき。島の無いページは JS ゼロのまま通常遷移。
CSS Modules・アセット・ソースマップ
クラス名をスコープ化する *.module.css、画像やフォントのハッシュ付き import、dev/prod 両方の end-to-end ソースマップ。
npm エコシステムそのまま
SSR は Rust が管理する Preact の Node サイドカーで動くので、既存のパッケージがそのまま使えます。
正直な開発体験
全画面エラーオーバーレイ、コードフレーム診断、ホットリロード、保存時の島ホットスワップ。
alpha について正直に。
Nowaki はまだ若いですが、コアは実在し、ヘッドレス Chrome まで含めて端から端まで検証済みです。現在地を正確に示します。
今できること
- dev / build / start / prerender
- レイアウト・ミドルウェア・action・API ルート
- Islands + 島間 SPA ルーター
- CSS Modules・アセット import・ソースマップ
- スコープホイスティング済みの本番バンドル
- デプロイアダプタ: Node・静的・Bun・Deno・Cloudflare edge
- ストリーミング SSR + 設定プラグイン(変換フック)
- npm 経由の Rust 不要インストール
ロードマップ
- Jetstream: サーバーリアクティブ島(チャンネル経由の HTML パッチ)
- Rust を本番ホットパスへ
- 状態保持(prefresh)HMR
- Next・Astro とのベンチマーク