✏️

Next.js + TypeScriptで作った学習管理アプリ『study-tracker』を振り返る

に公開

1. アプリ紹介

アプリ名: study-tracker

概要: CRUD機能を持つ学習管理アプリ

公開場所:
以下のリンクからご覧いただけます。
https://study-tracker.shunniehub.com

ソースコード:
https://github.com/Shunnie816/study-tracker-next

この記事では、個人開発で制作した過程や技術選定、工夫したポイントなどを踏まえて、アプリの紹介をします。

私のポートフォリオサイトのサブドメインにデプロイしていますので、こちらも参照ください。
https://zenn.dev/nekonoko2323/articles/99b04898ad97b8

2. 作った背景

私は現在、新卒3年目の文系出身フロントエンドエンジニアです。
入社前にReactを使った学習管理アプリを個人開発していましたが、業務で Next.js + React + TypeScript を使うようになったため、学習の一環としてアプリを作り直しました。

昨年、ポートフォリオ制作を行い、自分で購入したドメインにデプロイした経験を活かし、今回は サブドメインにデプロイ。今後制作するアプリも積み上げていく予定です。

自分の学習や成長の記録として残しておけるのも、個人開発の面白いところです。

3. アプリの機能・構成

シンプルで最低限の機能だけつけています。

機能紹介

  • 学習内容のCRUD操作(Create, Read, Update, Delete)
  • 画面数:3画面(学習記録、教材登録、学習記録一覧)

学習記録画面

  • 学習時間、教材を選択し、自由記述でメモを残すことが可能
  • 日々の学習内容を簡単に記録

学習記録画面のスクリーンショット

教材登録画面

  • 教材を登録、編集、削除可能

教材登録画面のスクリーンショット

学習記録一覧画面

  • 記録した学習内容が投稿順に表示
  • 投稿の編集はできないが、削除は可能

学習記録一覧画面のスクリーンショット

4. 技術スタックの選定

主な技術スタックと選定理由を共有します。

主要な言語・フレームワーク

  • TypeScript
  • React -v18
  • Next.js -v14.2.30

UIライブラリ

  • MUI
  • Storybook

テスト

  • React Testing Library
  • Vitest

バリデーションチェック

  • React Hook Form
  • Zod

データ操作・DB

  • SWR
  • Firestore

デプロイ

  • Firebase (App Hosting)

開発環境・ツール

開発環境

  • VSCode(Copilot proを中心にコーディングを補助)

ソース管理

  • GitHub

コンポーネント設計

  • Atomic Design

選定理由

今回の開発では、業務で利用している技術を中心に据えることで、実務と個人開発を結びつけながらスキルを定着させることを目的としました。

  • TypeScript / React / Next.js
     業務で日常的に使用している技術であり、個人開発でも活用することで知識の定着を狙いました。業務ではNext.jsのPages Routerしか使っていなかったため、App Routerの使い方を覚えることを目的として採用しています。

  • MUI
     UIライブラリは一つ得意なものを身につけたいと考え、有名かつ情報も豊富なMUIを選定しました。テーマ設定やコンポーネントのカスタマイズ性が高く、長期的に使える基盤になると判断しました。今回はコンポーネントのカスタムやグローバルなカスタムテーマの設定方法を覚えました。

  • Storybook
     業務でも活用しており、コンポーネント単位でUIを確認できる点が便利です。UIの再利用性を高めるため、個人開発でも導入しました。

  • React Testing Library / Vitest
     コンポーネントテストを行い、UIが意図した通りに動作するかを検証するために採用しました。業務ではjestを使用していたので、今回はVitestを採用しました。小規模アプリであってもテストを書いておくことで、リファクタリング時の安心感が得られます。

  • React Hook Form / Zod
     入力バリデーションを強化するために導入しました。React Hook Formはフォーム管理を効率化でき、Zodと組み合わせることで型安全なバリデーションが可能になります。業務で初めて使ったので、知識定着のためになるべくいろいろな機能を使うようにしました。

  • SWR / Firestore
     Firestoreをデータベースとして利用し、SWRでデータフェッチとキャッシュを管理しました。リアルタイム更新が必要な学習管理アプリにはFirestoreが相性がよく、SWRと組み合わせることで自然な画面更新を実現しました。

  • Firebase App Hosting
     デプロイはFirebaseのApp Hostingを利用しました。ホスティングやDB、認証などが一体となっているため、個人開発ではとても扱いやすい環境でした。また、Next.js用にApp Hostingが使えるので、デプロイも手軽にできます。

  • Atomic Design
     UIコンポーネントを整理するためにAtomic Designを採用しました。最初は戸惑いもありましたが、設計思想を理解したことで再利用しやすく拡張性のある構成を実現できました。ただ、今回はAtom, Molecules, Organinsmsなどそのままディレクトリ名として採用してしまったので結果的に管理が難しく、開発がしにくくなりました。今後は機能別にフォルダを分けていくようにしたいと思いました。

5. 開発過程

期間:約3か月

作業時間:平日1.5h、休日2~5h

作業の進め方:NotionでTODO管理、疑問やネタはZennの下書きにメモ

リリースを急ぐよりも学習を重視していたため、ゆったりとしたペースで進行しました。また、VSCodeでCopilotを利用することで、スムーズにコーディングができ、効率よく開発を進められたと感じています。

制作で意識したこと・こだわりポイント

今回のアプリ制作では、単に「動くものを作る」だけではなく、利用者にとって使いやすく、拡張性のあるアプリになるようにいくつかの点を意識しました。

ポイント 内容
ユーザーへのレスポンス バリデーションチェック時のエラー表示を工夫し、入力ミスにすぐ気づけるようにしました。フォーム送信時もデータ更新が完了したことがわかるフィードバックを表示し、安心して操作できるようにしています。
データ更新時の画面反映 Firestoreのデータ更新があった際にUIへ即時反映されるよう、リアルタイムリスナーと状態管理を組み合わせました。利用者が「更新されていないのでは?」と不安にならない自然な操作感を実現しています。
UIの一貫性と操作性 MUIのテーマ設定をベースに再利用性を意識してコンポーネントを分割。色やフォントを統一してデザインの一貫性を確保しました。また、ボタンやフォーム配置を工夫し、モバイル環境からでも快適に操作できるようにしています。

製作中に大変だったことと学び

制作期間が長くなった要因でもありますが、開発中にはいくつかの課題に直面しました。その中でも特に印象に残っているのは以下の3つです。

  • MUIのカスタマイズ
  • Firebase Emulatorの導入
  • Atomic Designの導入

MUIカスタマイズに苦戦したこと

これまではMUIのコンポーネントをそのまま利用する程度だったのですが、今回はアプリ全体のデザインテーマを設定し、独自の色やTypographyを適用するなど、一歩踏み込んだカスタマイズに挑戦しました。

ドキュメントを読み込むのに時間がかかったものの、小規模な変更から徐々に適用範囲を広げていくことで理解を深めることができました。結果として、色や文字スタイルを統一でき、見た目に一貫性が生まれただけでなく、自分好みのUIに仕上げられたため開発がより楽しくなりました。

Firebase Emulatorの導入と運用

Firestoreを使うことにしていたのですが、いきなり本番環境を触るのはリスクがあると考え、Firebase Emulatorを導入しました。初期設定自体は公式ドキュメントに従えばスムーズだったのですが、データが毎回起動のたびに消えてしまう点に苦労しました。

その対策としてデータのエクスポート・インポートを行う設定を試みましたが、ディレクトリの扱い方や起動コマンドの理解に時間がかかりました。最終的には、自動的にファイルを配置してくれる仕組みを活用し、さらにインポート・エクスポートをまとめて実行できるスクリプトを作成しました。また、ポートが競合して起動できない問題にも直面しましたが、不要なプロセスを自動で閉じるスクリプトを組み合わせることで解決しました。

結果として、make コマンドひとつで環境を立ち上げられるようになり、非常に快適に開発できるようになりました。

Atomic Design導入での試行錯誤

今回の開発で初めてAtomic Designを導入したのですが、当初は従来慣れ親しんだディレクトリ構成に引っ張られてしまい、うまく設計を進められませんでした。

そこで改めてAtomic Designの基礎を学び直し、「なぜこの手法を使うのか」「どんなメリットがあるのか」を理解することにしました。その結果、根拠を持ってコンポーネントを分割できるようになり、最終的には拡張性と再利用性の高いディレクトリ構成を組み立てることができました。

しかし、Atomic Designを馬鹿正直にそのまま採用してしまったので、開発体験としては微妙でした。コンポーネントの粒度の分け方や再利用性という観点を身につけるのには良いので、共通パーツを作るときなどには採用できそうです。そのほかのコンポーネントについては機能別にディレクトリを切って開発していく方が実用的だと感じています。

詳しくは以下の記事でも書いています。
https://zenn.dev/nekonoko2323/articles/c8a1cd0e50b875

6. 今後の展望

今回は学生時代に作っていたアプリをしっかり完成させつつ、業務で使っている技術領域の知識の定着を目的とした開発でした。

今後は先を見据えて、自分が経験したことのない方法や気になっている開発手法などを取り入れていこうと考えています。

具体例:

  • GitHub Issue駆動開発を試す
  • VSCode → Cursor移行をしてAI駆動開発を実践
  • 未経験のUIライブラリや設計手法を試す
  • V0などを使用したUIの自動生成

7. まとめ

ここまで読んでいただきありがとうございました。

個人開発は自由度が高く、学習と実践を同時に行えるので本当におすすめの学習方法です。
今後も個人開発で作ったものや、個人開発中の学びを発信できればと思っています。

これからエンジニアを目指す方や、同じエンジニアの方に少しでも参考になれば嬉しいです!

Discussion