Introduction
お疲れ様です ![]()
ジュニアフロントエンドエンジニアの
Kanataです。
世界初の和風モバイルWeb IDEを
2026年2月28日19:30に
リリースしました ![]()
今回はその備忘録と、
開発における技術的な知見を
一部共有します ![]()
Background
なぜ、和風モバイルWeb IDEを
作ろうと思ったのか。
理由は3つあります。
1.和風のIDEがまだなかったから
どのIDEも同じようなデザインばかりで、
「使っていて便利」 ではありますが
「使っていて心地良い」 IDEが
まだないなと感じていました。
「日本人が日本人のために
デザインしたIDEが欲しい」
という思い付きが
このプロジェクトの始まりでした。
2.ひらめきを即コードにしたかったから
毎日どこへ行くにも
ノートパソコンを常に持ち歩くのは
現実的ではありません。
手元のスマートフォンひとつで
アプリ開発を進めることができたら
とても便利だろうなと思いました。
3.アプリ開発の楽しさを広めたかったから
「プログラミングに興味はあるけれど、
まだスマートフォンしか持っていない」
という未来のエンジニアたちの
最初の一歩を後押しする
身近なIDEを作りたいと思い、
ユーザー登録、クラウド連携、課金、
広告、AIサジェスト、トラッキング、
テレメトリーをすべて排除した
導入ハードルが低いIDEに
しようと考えました。
Workflow
全部で2か月(188時間30分)
かけて企画からデプロイまで
完遂しました!
CMやLPの制作時間を加えると
190時間超になります ![]()
開発+宣伝で2か月(200時間)を
予定していたので、概ね計画通りです。
どのように進めていったのか、
プロジェクト内のファイルを
一部公開しながら解説します ![]()
Phase0:発案
LINE Keepメモを使って
浮かんだアイデアを
書き溜めていきます。
身近な人の困りごと(悩みごと)を
一緒に解決できるように
考えるクセを持っておくと
アイデアが浮かびやすいです ![]()
Phase1:企画
Googleドキュメントを使って
企画書を作ります。
アプリの概要、ターゲット、競合、
競争優位性、コスト、レベニューを
明確にします。
「誰のどういった課題を
どのように解決したいのか」
を考えるとアプリのコンセプトが
決まりやすいです。
本プロジェクトの核は、
「コードを書く楽しさ」を
モバイル端末から手軽に体験できる
ようにすることと、
モダンな仕様駆動開発(SDD)を
経験することに決まりました ![]()
Phase2:要件定義
企画書をもとに、
Googleドキュメントを使って
要件定義書を作ります。
最初から完璧なアプリを
作る必要はありません。
まずはターゲットのニーズを
満たすために必須の機能だけを
搭載したアプリ(MVP)
を考えます。
「こんな機能もあったらいいな」
は、バックログとして
要件定義書から
切り離しておきましょう。
Phase3:外部設計
企画書と要件定義書をもとに、
MediBang Paintを使って
デザインカンプを作ります。
日本の伝統色(和色)を
カラーパレットに採用しました。
ロゴ、アイコン、画面ラフ、
カラーパレットが完成したら、
それらをもとにCanvaを使って
画面サンプルと画面遷移図を作ります。
実際にアプリを使うことを
想像しながらデザインしましょう。
本プロジェクトでは
モバイルファーストな設計を意識し、
コンパクトな拡張キーボードバー
/検索・置換バーを搭載させたり、
ボタンの視認性と操作性を高めたり
といった工夫を凝らしました ![]()
Phase4:内部設計
要件定義書、画面サンプル、
画面遷移図をもとに、
Google Geminiを使って
技術スタックリスト、
コーディング規約、
ディレクトリ構成案、
開発ロードマップを作ります。
技術的に実現不可能な要素はないか
注意して壁打ちしましょう。
# コーディング規約
## 1. セキュリティ・技術選定
- プライバシーリスク(オフにできないトラッキングやテレメトリ)またはセキュリティリスク(既知の脆弱性やウイルス混入のおそれ)のある技術・ライブラリの提案および採用は**厳禁**。
- 架空のライブラリ、実在しないAPIメソッド、廃止された構文を提案するな。コードやコマンドを出力する際はその実在と動作確度を自己検証し、不確実な場合は代替案を提示せよ。
## 2. 設計原則
- KISS & YAGNI: 今必要な機能だけを**シンプルなコードで**実装せよ。
- DRY: ひとつのファイル内に**3回以上の重複がある場合のみ共通化**を行え。
- SOLID: 保守が困難になるまでは、SOLID原則を適用するな。
- SoC: **1ファイル1コンポーネント/1クラス**を徹底せよ。
## 3. 命名規則
| 形式 | 適用対象 |
| :--- | :--- |
| PascalCase | Reactコンポーネント名、クラス名、ファイル名(コンポーネント/クラス用)、インターフェース名、型(Type alias) |
| camelCase | 変数名、関数名、Custom Hooks名(use~)、メソッド名、プロパティ名、インスタンス名 |
| UPPER_CASE | グローバルな定数や、変更されないコンパイル時の値 |
| UPPER_SNAKE_CASE | 環境変数 |
| kebab-case | ディレクトリ名 |
## 4. TypeScript・実装詳細
- **欠落値の扱い**: `undefined` を使用し、`null` の使用を避けよ。
- **型定義**: 明らかな場合は型推論に任せ、不要な明示を避けよ。ただし、関数の戻り値や公開APIは明示せよ。
- **型安全**: `any` の使用を禁止し、`unknown` や適切なインターフェースで代用せよ。
- **安全性**:
- Non-null Assertion(`!`)は禁止。型ガード(if文等)を使用せよ。
- Type Assertion(`as Type`)は最小限に留め、型推論や定義での解決を優先せよ。
- **書式**:
- 行末には必ずセミコロン(`;`)を付けよ。
- インデントはスペース2つ(タブ禁止)。
Phase5:コーディング
要件定義書、画面サンプル、
画面遷移図、技術スタックリスト、
コーディング規約、
ディレクトリ構成案、
開発ロードマップを
プロジェクトフォルダに配置して、
Antigravityを使って
アプリを作ります。
PDFはMarkdownに変換しておきましょう
(AntigravityにPDFを
読ませようとすると少し面倒です)。
1ファイル1コンポーネント/1クラスずつ
実装させていくことを徹底させましょう。
Phase6:デプロイ
アプリが完成したら、
Cloudflare Pagesにデプロイします。
数あるホスティングサービスのなかで
無料プランでできることが最も多く、
おすすめです。
Phase7:CM制作
デプロイを達成した喜びを
噛みしめながら、
Google Geminiを使って
CMのBGMを作ります。
当初はCubaseを使って
BGMを制作する予定でしたが、
Phase5終盤でノートパソコンが故障して
新しいノートパソコンの購入や
初期設定/データ移行で想定外の
時間を取られてしまいました。
設定していた締め切りを絶対に守るために
柔軟に計画を変更し、Google Geminiを
使ってのBGM生成に切り替えました ![]()
BGMが完成したら、
Clipchampを使って
アプリを操作しながら撮影した
スクリーンショットや
アプリのロゴなどと組み合わせて
CMを作ります。CMは記憶に残りやすいように
15秒から30秒くらいにまとめましょう。
Phase8:LP制作
CMを公開したら、
はてなブログを使って
LPを作ります。
この工程でもAntigravityが
活躍してくれました。
要素を増やしていくことを見越して、
現時点ではシンプルな
LPにしておきました。
Challenges
モバイルWeb IDEという
特殊な要件を実現するにあたり、
直面した技術的課題とその解決策を
一部紹介します。
1.CodeMirrorのUIとの競合回避
本アプリのエディタエンジンには
CodeMirror 6を採用しています。
モバイル環境に最適化した
独自の検索・置換バーを実装したのですが、
CodeMirror標準の検索パネルと
表示が競合してしまう問題が発生しました。
これを解決するため、
CodeMirrorのUIはマウントせず、
プログラマティックAPIのみをインポートして
独自の検索・置換バーからCodeMirrorの
検索エンジンを操作する手法をとりました。
拡張機能の読み込み時にUIを無効化し、
検索ハイライト機能と
APIだけを有効にしています。
search({ top: true }),
独自の検索・置換バーの
UIコンポーネント内で、
ユーザーの入力を検知して
CodeMirrorの内部クエリと同期させます。
useEffect(() => {
if (activeView && isSearchOpen) {
const query = new SearchQuery({ search: searchWord, caseSensitive: false, literal: true });
activeView.dispatch({ effects: setSearchQuery.of(query) });
}
}, [searchWord, activeView, isSearchOpen]);
これにより表示の競合を完全に避けつつ、
検索ハイライトなどの
CodeMirror内部の強力な機能を
そのまま活用することができました。
2.AIによる破壊的行為の抑止
今回の開発ではAIを積極的に活用しましたが、
AIに任せきりにしないことを強く意識しました。
AIはコンテキストを見失ったり
複雑なエラーに直面したりすると、
「既存のロジックを丸ごと削除する」
「エラーを無視する」
といった破壊的な解決策を
提案してくることがあります。
そのまま提案を受け入れると
技術的負債が蓄積していき、
修正ループに陥ります。
そのため、AIが破壊的な
アプローチをとろうとした瞬間に
AIの作業を意図的に中断させ、
人間の手でコードを修正しました。
AIは強力なアシスタントですが、
コードの品質に責任を持つのは
エンジニア自身であるべき
だと考えています ![]()
Tips
全体を通して、用途に応じてAIを
使い分けることが重要です。
最新情報を得たい
Google検索のAIモード
抜け漏れや矛盾をチェックしてほしい
GeminiのThinkingモード
アイデアを広げてほしい
GeminiのProモード
仕様駆動開発(SDD)で使う
Gemini Pro、Claude Opus
Conclusion
最後までお読みいただき
ありがとうございました ![]()
これからも、
日々の学習で得た気づきや
試行錯誤の結果などを
積極的に発信していきます ![]()
不定期での発信になりますが、
よろしくお願いいたします。



