はじめに
Day 1では、このツールを自作した動機と開発方針について書きました。
今回は使用する技術スタックと、それぞれを選んだ理由について書きます。技術選定に正解はありませんが、「なぜその技術を選んだか」は後から振り返る際にも重要な記録になります。
技術スタック一覧
| 層 | 技術 |
|---|---|
| フロントエンド | Electron + TypeScript + Vite |
| バックエンド | Python + FastAPI |
| データ形式 | CSV(時間記録)/ JSONL(タスク)/ MD(ドキュメント) |
Electronを選んだ理由
今回のツールはデスクトップアプリとして動作させることを前提としています。その上でフロントエンドの基盤としてElectronを採用しました。
モデルにしたのはVS Codeです。開発者が日常的に使うツールとして、サイドバー・ヘッダー・メインエリアという構成は直感的に理解しやすいと考えました。
Electronはブラウザエンジン(Chromium)を内包しているため、HTML・CSS・TypeScriptでUIを構築しながらデスクトップアプリとして配布できます。クロスプラットフォーム対応(Windows・macOS・Linux)という点も、個人が自作するツールとして現実的な選択肢でした。
TypeScriptを選んだ理由
フロントエンドの言語としてTypeScriptを採用しました。
バックエンドにPythonを使用している構成において、フロント側の型定義が曖昧だとバックエンドとのデータのやり取りで意図しない型の不一致が発生しやすくなります。TypeScriptの型システムを使うことで、APIへ送信するデータの形式をコンパイル時に検証でき、実行時エラーを事前に防ぐことができます。
また、クラスベースのコンポーネント設計を採用しているため、TypeScriptの型による恩恵がコンポーネント間のインターフェース定義にも直接的に機能します。
PyWebViewとTauriを選ばなかった理由
PyWebView
PythonとWebフロントエンドを組み合わせる方法として最初に検討しました。しかし配布時の依存関係の複雑さと、Python環境のセットアップをユーザー側に求める点が課題でした。ElectronはNode.js環境ごとパッケージできるため、配布が単純になります。
Tauri
軽量なデスクトップアプリ基盤として有力な選択肢でした。しかし今回のバックエンドはPythonで構築しており、TauriはRustをバックエンドとして使用する設計が前提になっています。現時点では、Rustエンジンの開発とは別にツールのバックエンドをRustで書き直すコストが現実的ではないと判断しました。将来的にRustエンジンが完成した段階でTauriへの移行を検討する予定です。
FastAPIを選んだ理由
バックエンドのフレームワークとしてFastAPIを採用しました。
選定理由は3つあります。
1. 型定義との親和性
PythonのType Hintsを活用した型定義ができるため、TypeScriptとの型の整合性をバックエンド側でも担保しやすい構造になります。
2. 自動ドキュメント生成
FastAPIはSwagger UIを自動生成します。エンドポイントの動作確認をブラウザ上でそのまま行えるため、フロントエンドの実装前にAPIの挙動を単独で検証できます。
3. 責務分離との相性
今回の設計はフロントエンドとバックエンドを完全に独立させる方針です。FastAPIをAPIハブとして機能させることで、どちらか一方の変更が他方に影響を与えにくい構造を実現しています。
構成図
Frontend (Electron + TypeScript)
↕ HTTP
main.py ← APIハブ (FastAPI)
↙ ↘
times.py goals.py
↓ ↓
CSV JSONL / MD
おわりに
今日は技術スタックとその選定理由を書きました。
選定の基準は「完全ローカルで動作すること」「配布が現実的であること」「フロントとバックの責務を明確に分離できること」の3点です。
Day 3では時間記録機能の設計と実装について書く予定です。フラグ管理による二重押し防止や、月別CSV出力の設計判断など、シンプルに見えて考えることが多かった部分を記録します。
この記事は連載「クラウドに依存しないマイルストーン管理ツール開発記」のDay 2です。