Tkinterの限界と、新しい技術の選択
Python版のリリースから約3年。ユーザーからのフィードバックを踏まえ、 新しい技術基盤での再開発を決定しました。 本記事では、技術選定の過程と、その背景にあった課題を紹介します。
Python版の課題
Python版は多くのユーザーに利用されましたが、開発・運用を続ける中で以下の課題が明らかになりました。
- UIの古さ - Tkinterは1990年代から使われているライブラリで、現代的なデザインの実現が困難
- 拡張性の限界 - コードベースの複雑化により、新機能の追加が困難に
- パフォーマンス - 大量の画像処理時に動作が重くなる
- 保守性の低下 - コードの見通しが悪くなり、バグ修正に時間がかかるように
特にUIについては、Tkinterの制約が大きく影響していました。 機能を追加したい、もっと直感的な操作を実現したいと思っても、 Tkinterでは実現が難しいケースが多くありました。 そもそもPython版は機能が少なく、より多くの機能を使いやすく提供するには 新しい技術基盤が必要でした。
これらの課題を解決するには、部分的な改修ではなく、 新しい技術基盤での再開発が必要と判断しました。
型管理の問題
Python版で特に深刻だったのが、データの扱いに関するバグの多さです。
プログラムでは「型」という概念があります。 例えば、「点数」には数値(80、95など)が入るべきで、文字(「良い」など)が入ると計算できません。 Pythonは柔軟な言語で、こうした型のルールを厳しく指定しなくても動作します。 これは手軽さの反面、私のように雑なコードを書いてしまうと、 問題のあるコードでもそれっぽく動いてしまい、後から発覚するリスクがあります。
プログラムの規模が小さいうちは問題になりませんが、 機能が増えるにつれて以下のような問題が出てきました。
- 突然のエラー - ユーザーが操作している最中に、予期しないエラーが発生する
- 原因の特定が困難 - どこで問題が起きたのか、追跡するのが難しい
- 修正が怖い - ある場所を直すと、別の場所で問題が起きる可能性がある
- 仕様がわからない - 「この機能に何を渡せばいいか」が不明確
例えば、「点数が入っているはずの場所に、空っぽのデータが入っていた」 といったバグが頻発しました。 私の書き方に問題があったのですが、型を厳密に管理していなかったため、 実際に動かすまで気づけず、ユーザーからの報告で初めて発覚することも少なくありませんでした。
検討した技術
デスクトップアプリケーション開発のフレームワークとして、以下を検討しました。
軽量で高速な実行ファイルを生成できる新しいフレームワーク。 バックエンドにRustを使用するため、メモリ安全性が高く、パフォーマンスも優れています。
課題: Rustの学習コストが高い。エコシステムがまだ発展途上。
Googleが開発するクロスプラットフォームフレームワーク。 モバイルアプリ開発での実績が豊富で、UIの表現力が高い。
課題: デスクトップアプリとしての実績が少ない。Dart言語の習得が必要。
Visual Studio Code、Slack、Discordなど、世界的に利用されているアプリで採用実績あり。 Web技術(HTML/CSS/JavaScript)がそのまま使えるため、学習コストが低い。
課題: アプリサイズが大きくなりがち。メモリ消費量が多い。
Electronを選んだ理由
最終的にElectronを採用しました。決め手となったのは以下の点です。
- UIの自由度 - HTML/CSSによる柔軟なデザインが可能。CSSフレームワークやコンポーネントライブラリも利用可能
- 豊富な実績 - Visual Studio Code、Slack、Discordなど大規模アプリでの採用実績があり、安定性が実証されている
- エコシステム - npm経由で利用可能なライブラリが豊富。問題解決の情報も多い
- TypeScriptとの親和性 - 静的型付けによる品質向上が期待できる
- 将来の拡張性 - 技術的にはWebアプリへの展開も可能
「Electronは重い」という批判は認識していますが、採点ソフトウェアの用途では 起動時間やメモリ消費が致命的な問題になるケースは少ないと判断しました。 むしろ、UIの品質向上と開発効率の改善を優先しました。
採用した技術スタック
Electron版の技術スタックは以下の通りです。
- Electron - デスクトップアプリケーションフレームワーク
- Next.js / React - UIフレームワーク。コンポーネントベースの開発が可能
- TypeScript - 静的型付けによる型安全な開発
- Tailwind CSS - ユーティリティファーストのCSSフレームワーク
- Prisma / SQLite - データベースアクセスとデータ永続化
特にNext.jsとReactの組み合わせにより、 画面の各パーツ(ボタン、入力欄、一覧表示など)を独立した部品として開発できるようになりました。 Python版では画面全体をまとめて管理していたため、一箇所の修正が別の場所に影響することがありましたが、 Electron版では各機能が独立しているため、安全に修正・追加ができます。
TypeScriptへの移行
PythonからTypeScriptへの移行は、今回の再開発で最も効果のあった変更の一つです。
TypeScriptはJavaScriptに静的型付けを追加した言語です。 プログラムを実行する前に、「この変数には数値しか入らない」「この関数は文字列を返す」といった ルール違反を自動でチェックしてくれます。 Python版では、こうした問題がユーザーの操作中に突然エラーとして表れることがありましたが、 TypeScriptでは開発中に気づけるようになりました。
- 「この関数にはこの形式のデータを渡す」というルールが明確になり、間違いに早く気づける
- コードを書いている最中に、次に何を書けばいいか候補が表示される
- ある箇所を修正したとき、影響が出る他の場所を自動で教えてくれる
- コード自体が「この機能は何をするか」の説明書になる
結果として、ユーザーが操作中に突然エラーが出る、という問題は大幅に減少しました。 開発者としても、「この変数には何が入っているか」を常に把握できるため、 安心して機能追加や修正ができるようになりました。
開発期間は約1年。2025年11月にElectron版の最初のリリースを行いました。