Misora 開発ノート Part.3
Claude Code を利用して静的サイトとして WebRTC SFU Sora さえあれば利用できるミーティングツールを開発している。プロダクト名は Misora (み空色) 。
全くコードは書いていないし、テストコード以外は見てない。CLAUDE.md をしっかり書いて、指示は複雑なタスクになりそうな場合は、かなり詳細に指示してる。E2E テストとコンポーネントテストはかなりしっかりレビューしている。
せっかくなのでメモを定期的に書いている。
音量でアイコンが跳ねる
よくある会議システムを参考に音量インジケーターを作ってみたが、が不評だったので、Discord を参考にアイコンがしゃべると跳ねる方式を採用。数分で出来た。

ミュートをハードミュートへ
マイクやカメラをミュートしたタイミングでマイクやカメラのランプが付いている状態は凄く嫌がられる。通常はミュートはただ MediaStreamTrack をミュートして終わりだが、ちゃんとデバイスを話してミュートするように切り替えた。
退室時にデバイスをすぐに離す
退室ボタンを押して退室した際にマイクやカメラデバイスをつかんでいるのを離すようにした。当たり前のことではあるのだが、遅いと「なんでランプついてるの?」と嫌がられる。
ホスト機能
一般的な会議システムでよくある「ホスト機能」をとりあえず表示だけ実現した。



ホストかどうかを判断する仕組みはとてもシンプルにした。
Misora では URL を共有するにあたり、指定したシークレットキーを利用して生成した JWT が access_token として URL パラメーターに含まれる。この URL パラメーターに含まれた access_token がそのまま Sora で利用する際の認証トークンとなる。
Misora では利便性のため Sora のシグナリング URL やシークレットキーを OPFS に保存する仕組みがあり、その仕組みを利用している。もちろん保存しないこともできるので保存しなければホスト機能は利用できない。
つまり JWT を生成するために必要なシークレットキーが保存されている場合、この保存されているシークレットキーを利用して URL パラメーターにある access_token がベリファイできるユーザーをホストとして見なすという仕組み。

ちなみにホストは今のところ「ホスト」というラベルが付く以上の機能はない。
実運用
お手伝い先とのうち合わせに利用してみたが、特に困ることなく利用できた。画面共有機能がやはり便利。
なにより静的サイトなのでとにかく軽い。とはいえ React Router が重いのか 120 kb 程度。100 kb 切りたいが、難しそう。
依存ライブラリ
依存ライブラリは今のところ増やす予定はなし。
"devDependencies": {
"@biomejs/biome": "2.0.6",
"@playwright/experimental-ct-react": "1.53.1",
"@playwright/test": "1.53.1",
"@tailwindcss/vite": "4.1.11",
"@types/node": "24.0.7",
"@types/react": "19.1.8",
"@types/react-dom": "19.1.6",
"@vitejs/plugin-react": "4.6.0",
"dotenv": "17.0.0",
"playwright": "1.53.1",
"tailwindcss": "4.1.11",
"typescript": "5.8.3",
"vite": "7.0.0"
},
"dependencies": {
"jose": "6.0.11",
"react": "19.1.0",
"react-dom": "19.1.0",
"react-router-dom": "7.6.3",
"sora-js-sdk": "2025.2.0-canary.1",
"zustand": "5.0.6"
}
ここまでのコード量
1 行も自分では書いてない。今は小さなタスクを依頼して Claude Code にお任せな状態。細々したバグを取る状況。あとデグレ対策でのテスト追加。

Claude Code
- hooks がでたのでとりあえず Biome による fmt だけ設定してみた。
- 相変わらずデグレが凄い
- コンポーネントテストはかなり良い
- E2E テストもかなり良い
今後
コンポーネントテストをもう少し増やしたい。デグレを徹底的に抑えたい。
次はミュート共有と挙手機能を整備していきたい。また、色々とバグがあるのでバグ取りもやっていく。
サイズがそんなに小さくないのも気になっているが、圧縮して 128 kB 未満ならまぁいいかなと。
dist/index.html 1.13 kB │ gzip: 0.61 kB
dist/assets/index-CAPEYP9o.css 31.48 kB │ gzip: 6.51 kB
dist/assets/index-C8GlTpHG.js 421.62 kB │ gzip: 123.30 kB
✓ built in 790ms
そろそろ DuckDB-Wasm を利用した解析機能にも着手したい。