1.はじめに
なぜこのアプリを作ったのか
英語学習の課題
私は現在英語学習をしており、以下の目標を持っています。
- 英作文作成能力向上
- 語彙力向上
- 英語脳の構築(日本語を介さない学習)
既存ツールの限界
これまでChatGPTを使った英会話や、オンライン・オフラインの英会話レッスンを試してきましたが、それぞれに課題を感じてきました。
まず、英会話学習にChatGPTを活用できるのではと思い、英語のみで会話をしてみました。確かに便利ではあるものの、プロンプトで会話のスタイルを指定しても、会話が進むにつれてAIが最初の指示を忘れてしまうことが多く、レスポンスも長くなりがちで、自然な会話にはなりませんでした。
また、ChatGPTとの会話はその場限りになりやすく、会話中に出てきた単語を後から復習できないため、なかなか語彙が身につかないという課題も感じました。
一方、オンラインやオフラインの英会話レッスンも体験しました。実際に話す環境に身を置くことはとても良い経験ですが、知らない単語や表現に出会っても、その場限りで終わってしまい、繰り返し練習したり復習したりする仕組みがないため、語彙力がなかなか増えないと感じました。
ChatGPTとの英会話
- ❌ プロンプトを指定しても自然な会話にならない
- ❌ レスポンスが長すぎて実用的でない
英会話(オンライン、オフライン)
- ❌ 知らない単語に出会っても、その場限りになる
- ❌ 繰り返し練習する仕組みがない
開発のきっかけ
ハッカソンイベントでチーム開発を体験し、英会話学習アプリを開発しました。
その経験を通じて、自分自身が抱えている課題を解決するアプリケーションを作れるのではないかと考えたことが、このアプリを作るきっかけとなりました。
※このアプリを作ることについて、チームメンバー全員の承諾を得ています
なぜすべて英語にしたのか
英語学習を進めるにあたり、牛尾剛さんの著書『ITエンジニアのゼロから始める英語勉強法』を大変参考にしています。
本書の「第2章 英語勉強法の原則」では、「ダイレクト理解の原則」が紹介されています。
これは「英語を日本語に翻訳せず、英語のまま理解する」ことの重要性を説いたものです。
著者によれば、ダイレクト理解を推奨する理由は以下の3点です。
- ネイティブとの会話で、いちいち日本語に変換していると会話のスピードについていけない
- 英語と日本語は1対1で翻訳できるものではない
- 日本語を介すると、英語脳の働きが低下してしまう
この考え方に共感し、私も英語学習やアウトプットはできるだけ英語で行うようにしています。
2.完成したアプリ紹介
コンセプト
「幼児が言葉を覚えるプロセス」 をモデルにした学習アプリ
- 分からなくてもとりあえず使ってみる
- AIに間違いを指摘してもらう
- 繰り返し練習で身につける
学習フロー
単語を使ってみる → その単語を説明できるようになる → 単語を習得
3.機能紹介
機能
(1)Practiceページ - AI会話練習
身につけたい単語をAIと会話で練習
- ログイン状態で個人/共通単語リストを切り替え可能
- 単語リストからランダムピックアップ
- タグで対象の単語リストを選択
- 「Try」: 単語を使った文章作成
- 「Explain」: 単語の意味説明
- 「Send」: メッセージを送信
- 「Edit」: 単語のステータスを変更
- 「Clear」: 会話履歴を消去
UX改善ポイント
- 初期状態で使えないボタンを非表示
- テキストエリアは必要時のみ表示
(2)Add Wordページ - 単語追加
覚えたい単語、紐づけるタグを単語リストに追加
- シンプルな入力フォーム
- ログイン状態で追加先を自動判定

(3)Dictionaryページ - 英英辞典
英英辞典として使用 + 会話継続
- 単語の意味をAIが英語で説明
- そのまま会話を続行可能
- 覚えたい単語は「Add Word」で追加
- 「Clear」ボタンで会話リセット
「Ask AI」、「Add Word」、「Clear」ボタンを使用している画像
(4)Word Listページ - 単語管理
学習進捗の管理
- 単語の編集・削除
- 学習状態管理(Mastered, Try, Explain)
- 進捗の可視化

(5)How to Useドロワー
ユーザーフィードバックから生まれた機能
- アプリの使い方を説明
- 日本語ページも実装

(6)Tagフィルター
タグによるフィルターで、Practice対象の単語やWord Listの表示を切り替え
- 各単語にタグを追加できるように実装
- Practiceページ、WordListページの両方でタグによるフィルターが可能
(7)ログイン機能
Supabase Authを用いてGoogle認証を実装。
実装内容
- Google認証によるワンクリックログイン
- ログイン状態に応じた個人/共通単語リスト切り替え
- セッション管理の自動化
開発体験
- SupabaseのGoogle認証が簡単
(8)その他 新しく学んだHooks
- useMemo: 特定の値が変わった時のみ計算を実行
- useRef: DOM要素への直接アクセス(スクロール制御)
useMemo - 無駄な再計算を防ぐ
課題: Word Listページで単語の状態(チェックボックス)に変更があった時のみ「Update」ボタンを有効にしたい
解決: useMemoで単語の変更検知を必要時のみ計算するように最適化
useRef - スムーズなユーザー体験
課題: AI会話でメッセージ送信後、最新メッセージが画面外に出てしまい、ユーザーが手動でスクロールする必要があった
解決: useRefで最新メッセージの位置まで自動スクロール機能を実装
4. 技術スタック
フロントエンド
技術 | 用途 |
---|---|
React + TypeScript | コンポーネントベース開発と型安全性 |
Tailwind CSS | ユーティリティファーストのスタイリング |
Vite | 高速な開発環境とビルドツール |
バックエンド・インフラ
技術 | 用途 |
---|---|
Supabase | PostgreSQLベースのBaaS、認証・リアルタイム機能 |
Firebase Hosting | 静的サイトホスティング、CDN配信 |
Gemini API | 英語学習用の自然な対話生成 |
開発・デプロイ・CI/CD
技術 | 用途 |
---|---|
Git + GitHub | バージョン管理・ソースコード管理 |
GitHub Actions | CI/CDパイプライン・自動化 |
Firebase CLI | デプロイメント自動化 |
ESLint + Prettier | コード品質管理・フォーマット統一 |
アーキテクチャ概要
システム構成図
認証フロー図
データベース構成図
5. 開発過程での学び
開発で学んだこと・ハマったポイント
1. アイデア出しの難しさ
最初は「英会話ができるだけのアプリ」を考えていました。
たとえば、AIに歴史上の人物のふりをしてもらい会話する――それだけでも面白いと思ったのですが、@Sicut_studyさんに壁打ちしてもらったところ、「それだけだと弱い」とアドバイスをもらいました。
そこから「何を作ればいいのか?」をかなり悩み、試行錯誤の末、今の形に落ち着きました。
実際に作り始めてからも方向性を何度か変え、
「AIに作った英作文についてアドバイスしてもらうアプリ」からスタートし、
「AIと会話するアプリ」や「知らない単語に出会うためのアプリ」へと発展。
さらに、「AIと会話するアプリ」「英英辞書」「英単語を覚えるアプリ」へと、
段階的に方向性をシフトしていきました。
Ankiという単語暗記アプリも使ったことがありますが、
「対話しながらの方が記憶に残りやすいのでは?」と考え、今回のアプリを作っています。
今後は実際に使ってみて、本当に単語を覚えられるか検証していく予定です。
課題:
・何を作るべきか明確にするのが難しい
解決策:
・自分の実体験から課題を抽出する
・詳しい人に相談する
・作りながら企画自体をブラッシュアップする
2. ユーザー目線の重要性
気づき:
・作り手には分かっても、ユーザーには分からない
エンジニア仲間からのフィードバック
- ❌ アプリの使い方がわからない → ✅ How to Useページ作成
- ❌ 初期状態で使えないボタンがあり、わかりにくい → ✅ 必要時のみ表示
自分では意図が分かっているので迷わず使えるのですが、ユーザー目線では「どのボタンを押せばいいのか分からない」という声がありました。
特にPracticeページには 「Try」「Explain」「Send」「Edit」「Clear」と5つのボタンが並んでおり、初めて使う人には迷いやすい構成でした。
そこで、最初は 「Try」と「Explain」ボタンだけを表示し、他のボタンは必要なタイミングで表示するように変更しました。
この改善はエンジニア仲間からのアドバイスがきっかけです。
また、アプリ自体は英語のみで作っている点に価値があると考えていましたが、「日本語での説明も欲しい」という意見も多くいただきました。
そのため、英語に加え、日本語で使い方を解説するドロワー(説明用パネル)も追加しました。
3. AIを活用した開発効率化
アプリ開発においては、ロジック部分や骨組みなど必要な部分は、AIに質問しつつもなるべく自分で実装するように心がけました。
たとえば、フォルダ構成や入力画面の設計、useStateやuseEffectをどこで使うかといった細かい部分は自分で考えて作りました。
CSSでは、「やりたいこと」、「実現したいイメージ」、「実装したコード」をAIに伝え、Tailwind CSSでたたき台となるコードを作ってもらい、そこから自分で調整していきました。
デザインやCSSはもともと苦手意識がありましたが、AIが自分では思いつかないようなデザイン案を提案してくれたので、とても助かりました。
まとめ:
・ロジックや構成は自分で考え、必要な部分だけAIに相談
・デザインやCSSの初期案はAIに任せて効率化
・AIの提案を活用することで、苦手な分野でも高品質なアウトプットが得られた
4. 認証実装の簡単さ
Supabase Authを使ったGoogle認証の実装は、とても簡単でした。
わずか数行のコードで本格的な認証機能を追加でき、初めてGoogle認証を実装する自分でも驚くほどスムーズに進みました。
実際、Supabaseが認証まわりの面倒な部分をほとんど自動でやってくれるので、開発効率が大きく向上します。
唯一つまずいた点は、認証後に「元いたページにリダイレクトさせる方法」が最初は分からず、少し苦戦したことです。
それ以外は、想像以上に簡単に認証機能を導入できました。
まとめ:
・Supabase AuthでGoogle認証の導入が非常に簡単
・数行のコードで本格的な認証が実現できる
・認証後のリダイレクト処理だけ少し工夫が必要だった
5. テスト実装での苦労
ハマったポイント:
- Supabaseのチェーンメソッドのモック作成方法
- テストで期待する結果を明確にすることの重要性
- APIが呼ばれた後のUIを確認するのか?
- それともAPIが呼び出されたこと自体を確認すれば良いのか?
APIが呼ばれた後のUIをテストで確認したい場合、モックデータを変更しないとUIの変化が分かりません。
一方で、「APIが呼び出されたこと」だけを確認したい場合は、モック関数の呼び出しを検証すれば十分です。
この区別が曖昧なままテストを書いていたため、どこまで検証すればよいか迷走してしまいました。
また、モックデータがテスト間で書き換わってしまい、他のテストに影響してテストが失敗する現象も発生しました。
https://qiita.com/like-mountain/items/fb47c0f0afa2762570e5
6. 追加開発について
アプリ完成後、実際に自分で単語を登録して使ってみたところ、単語カテゴリ(タグ)がない状態で多く単語を登録すると、登録した単語がなかなか出現しないという問題が発生しました。
(100語登録してあると、Practiceで出現する確率は1/100と低い確率になってしまう)
この課題を解決するため、単語カテゴリ (タグ) の仕組みを追加しました。
この対応を通じて、単語とカテゴリ(タグ)の多対多の関係を設計・実装する経験を積むことができました。
6. 今後の展望
- 今後も自分で実際に使いながら、アプリをブラッシュアップしていく予定です
- 繰り返しAIと会話しながら単語学習を続けることで、より効率的に語彙を身につけられる仕組み作りを目指しています
- 使っていく中で 「こんな機能があったら便利だな」 と感じたものがいくつか出てきたので、今後も新しい機能を追加実装していく予定です