1人でのSaaS開発を支えた技術スタック
技術スタックをまとめた記事をたまに見かけますが、気になるサービスの裏側を知れるのは「隣のクラスの気になるあの子」のFacebookを初めて覗くようなドキドキ感があります(笑)
しかし残念ながら、このようなブログが紹介している技術スタックは成熟したサービスのものに限られており、立ち上がったばかりのSaaSに関するブログ記事はほぼ見かけません。そのため、現在のEkakiの技術スタックの選定に役立つ情報をなかなか見つけられず、多くの失敗を繰り返してきました。
ということで、今回のブログでは私がこれまでにどのような技術スタックを採用してきたのかを紹介します!SaaSの開発を始めたばかりの方やSaaSを新しく開発する予定のある方の参考になれば嬉しいです!
ちなみに、私達の創業ストーリーに関しては別のブログ記事で紹介しているので、ぜひご覧下さい!
背景
以下が、今回の技術スタックの選定に大きく影響している重要なバックグラウンドになります。
- 開発経験. 大学2年の秋からコンピューターサイエンスを独学し、その過程でプログラミングに触れている。そして今回の開発が初めての開発経験であり、ゼロから学びながら進めてきた。Ekaki以外の組織での開発経験がないため、成長中/成熟したサービスに関する知見は少ない。
- カバレッジ. 共同創業者の前澤が参画するまでは、開発に関することを全て一人で担当していた。Ekakiの開発においては、特にフロントエンドに多くの時間を費やしている。
- 深層学習の研究. 2021年の「未踏アドバンスト」に応募しており、2021年1月から2021年3月の期間はアプリケーション開発から身を引き、深層学習ベースの音声認識の研究を行っていた。「未踏アドバンスト」は二次面接でアウト。
- 主な情報源. 技術スタックの選定における情報源の多くは英語のサイト。そのため、利用しているサービスの中には日本語対応の弱いものも含まれている。
言語
- TypeScript. 開発当初はJavaScriptで統一していたが、サービスの規模が大きくなるにつれて、昔書いたコードを見返した時に「このコードは何をしているのか」と忘れることが多くなった。TypeScriptを採用したことで変数や引数の型が可視化され、コードの可読性が大幅に向上した。共通の型をフロントエンドとバックエンドの両方で利用することで、データモデルを変更した際のコード修正もしやすくなった。そして型定義ファイル自体がドキュメントにもなる。
フレームワーク/ライブラリ
MERN(MongoDB, Express, React, Nginx)スタックを採用しています。当時はUdemyのMERNスタックのコースを受講しながら開発を始めたため、それ以外の選択肢が存在しなかったのが本音です。エンジニア脳になると全てを自前で開発したくなりますが、プロダクトのコア部分に多くの時間を割くためにも、できる限りオープンソースに頼ることにしています。
フレームワーク/ライブラリを選択するときに重視していることは二つあります。
- 開発者コミュニティ. 技術のシェアが高ければ高いほど利用者側の開発者も多いので、何か行き詰まった時のサポート(ドキュメント/StackOverflow/ブログなど)が充実している。ニッチなライブラリに関しては、直近のコミット数や未解決のイシュー数を調べることで、今後致命的なバグが生じた場合の作成者側の対応の早さを確認している。
- 少ない技術で多くを達成. 頭の切り替えコストを抑えるために、利用するフレームワークの数はできるだけ少なくしている。一方でライブラリに関しては、コードレベルで自分好みに抽象化できるので、良いライブラリがあれば積極的に採用している。
全体
- Lerna. フロントエンドやバックエンドのような複数のパッケージを一つのレポジトリで管理する(=モノレポ)ためのツール。全てのパッケージのスクリプトを同じ階層から実行できるのはとても便利。ローカルのNPMパッケージ的なものも簡単に作れる。
- I18next. Ekakiは現在日本語のみの対応だが、近い将来には複数言語に対応させる予定のため、現時点から多言語化(i18n: Internationalizationの略)を意識している。少しでも多言語化の可能性があるのであれば、開発の初期段階から入れた方が良いツール。
フロント系
- React. 一番人気のフロントエンドフレームワーク。Reactを知る前と知った後では、作れるアプリケーションの幅が劇的に広がった。自由度が高い一方で、Reduxなどを用いたステート管理は非常に複雑であり、システム的な思考スキルが求められる。
- Electron. デスクトップアプリを作成するためのフレームワーク。デスクトップアプリは配布までのフローを自分で設計しなくてはいけない上、実際に配布可能な形にしないと確認できない機能(eg. 自動アップデート機能)が多く存在する。開発リソースが十分な場合を除き、絶対必要でない限りは開発すべきではない。
- Styled Components. JavaScriptファイルに直接CSSを書き込めるライブラリ。JavaScriptファイルとCSSファイルを行き来する必要がなくなる。Reactのようにコンポーネント単位でスタイルを再利用することも可能。
- NextJS. Reactをベースにしたフロントエンドフレームワーク。Ekakiのランディングページで利用している。アプリのビルド時に静的なHTMLファイルを作ってくれるため、高速なサイトとSEO最適化の二つを達成できることが個人的なオススメポイント。
- Tailwind CSS. HTMLのClass上から要素のスタイリングができるフレームワーク。Ekakiのランディングページで利用している技術。レスポンシブなサイトを高速で作れることに加え、Bootstrapなどと比べてUIのカスタマイズ性も高い。
バックエンド系
- Express. APIサーバーを簡単に構築できるフレームワーク。他のフレームワークを検討したことはないが、今のところ特に困ったこともない。
- Socket.io. WebSocketサーバーを簡単に構築できるライブラリ。クライアントからのイベントを受信しつつ、任意のタイミングでサーバー側からクライアントにイベントを送信できる。ソケットの管理・ステートの管理・コンフリクトの対処などは非常に難しいため、本番環境で利用できるようになるまでは時間がかかる。
- Mongoose. スキーマレスであるMongoDBにスキーマ的な要素を加えたライブラリ。スキーマを定義することで、スキーマに沿わないドキュメントの作成などを事前に阻止してくれる。TypeScriptとの相性が悪いのがデメリット。
深層学習系
前述した2021年の「未踏アドバンスト」では、オンデバイスのE2Eの音声認識モデルの開発を予定していました。現在は深層学習系の開発は行っていません。
- PyTorch/Tensorflow. 元々はEmformerというモデルを論文実装した上で改良していたが、GitHub上に挙げられているその他の音声認識モデルも勉強目的で実装していた。最初はPyTorchを利用していたが、オンデバイスに最適化するためにも、TFLiteという形式へ変換可能なTensorFlowに途中から変更した。
利用中の外部サービス
インフラ
- Docker. Dockerコンテナを作成することで、Dockerをサポートする全ての環境で同じようにアプリケーションを動かすことができる。チーム開発に役立つことはもちろん、ほとんどのクラウドサービスがDockerコンテナによるホスティングをサポートしている。
- Amazon ECS. AWS上で簡単にDockerコンテナを利用できるフルマネージド型のサービス。データベース以外のEkakiの全サービスはECS上で稼働している。
- AWS Copilot. Amazon ECS上にアプリケーションを簡単にデプロイできる、公式からのお墨付きのCLIツール。Docker ComposeやECS CLIなども検討したが、デプロイまでの工程数の少なさと複雑なアプリケーションにも対応可能な点が特徴。クラウド周りの経験が浅くても使いやすい。
- Mongo Atlas. MongoDB社が提供するクラウド型のデータベースサービス。データのバックアップ設定やMongoDBが得意とするスケーリングを簡単に行うことができる。
CI/CD
- Github Actions. GitHubが提供するCI/CD(継続的インテグレーション/継続的デリバリー)のサービス。最初はTravisを利用していたが、ソースコードにアクセス可能なサービスを減らしたかったことに加え、GitHub上でCIの状況を簡単に確認したかったことから乗り換えた。
- CodeCov. プログラムのソースコードがテストされた割合(=カバレッジ)を可視化してくれるサービス。GitHubのREADMEにバッチを載せていること以外の用途はない。本来は入れなくても良いサービス。
モニタリング
- Sentry. フロントエンドで発生したエラーログを収集してくれるサービス。現在はウェブアプリ・デスクトップアプリ・ランディングページのエラーログを収集している。
- Uptime Robot. ウェブサイトの死活監視サービス。指定したウェブサイトが落ちていないかを定期的にチェックしてくれる。現在はウェブアプリとランディングページを監視している。
メール
- SendGrid. APIベースのメール配信サービス。新規登録時の認証メールやパスワードの再設定メールの送信などに用いている。Mailchimpも検討したが、SendGridと比較してドキュメンテーションが読みづらく、APIの機能も限られていた。
分析
- Google Analytics. ユーザーの行動をページビュー毎に解析するツール。「何人がサイトに訪れたのか」「どのページをどれくらい閲覧したのか」などを確認できる。現在はランディングページの訪問者数を調べるためだけに使っている。
- Mixpanel. ユーザーの行動をイベント毎に解析するAPIベースのツール。ボタンクリックのような細かなイベントを収集できるため、プロダクトを詳細に解析したい場合に役立つ。Y Combinatorの講義でもオススメされている。ドキュメントを読むことに慣れていないと、公式ライブラリの使い方に苦戦するかもしれない。
決済
- Stripe. APIベースの決済サービス。Ekakiのサブスクリプション決済のバックエンドに用いている。Stripe以外のサービスには、税関係の計算などもまとめて管理してくれるPaddleや、BASEから分社化したPAY.JPなども存在するが、Stripeの認知度と「世界一読みやすいドキュメンテーション」と呼ばれるサービスを超えるモノは存在しなかった。
サポート
- Zendesk. 電話/メール/SNSからの問い合わせを一元管理できるサービス。ランディングページやウェブアプリのウィジェット(右下の丸いボタン)からの問い合わせを管理している。非公式のライブラリを使うことでウィジェットの表示方法をカスタマイズできる。Driftは表示方法のカスタマイズ性が低く、Intercomはチケット管理機能が弱かった。
- Typeform. 一問一答型のフォームを作成できるツール。主にランディングページからの問い合わせを管理している。以前はフォームを自作し、送信リクエストをFormrunに投げていたが、多言語化やモバイルに対応したフォームを作成するのが面倒だった。TypeformのUI/UXは非常に洗練されており、公式のライブラリを使うことで表示方法もカスタマイズできる。
デザイン
- Figma. 無料から使えるデザインツール。アプリケーションやランディングページのデザインを管理している。Figma以外のツールは検討したことがないが、これまで一度も困ったことはない。
- Flaticon. 様々なアイコンをダウンロードできるサービス。Flaticonよりもアイコン数の多いサービスは、今のところ発見していない。ついこの前まではSVGが無料でダウンロードできたが、今は課金をしなければSVGをダウンロードできない。
ドキュメント
- Contentful. APIベースのコンテンツ管理サービス。Ekakiのブログ記事を管理している。Headless CMSとも呼ばれており、ブログのUIを自由にカスタマイズできるのが特徴。最低限のコーディングスキルがあり、サイトのデザインを統一したい場合はオススメ。Contentfulを選んだ理由は、UI/UXとドキュメンテーションが優れていたため。
- Notion. 社内のドキュメント&タスク管理ツール。ファイル形式ではなくページ形式で管理できるのが一番のオススメポイント。興味本位でClickUpやCodaも利用してみたが、全てをブロックという単位で管理できるNotionの方が圧倒的に使いやすい。すぐに必要な情報にアクセスできることから、タスク管理もTrelloからNotionに乗り換えた。
まとめ
以上が、Ekakiの技術スタックの紹介となります。技術スタックの選定は一人で行ってきましたが、実際の開発内容に関しては共同創業者の前澤が参画してから大きく変わりました!サービスとしてもまだまだ駆け出しのため、これから新しく追加したり変更したりすることは頻繁に起きると思います!このブログに関する質問などありましたら、ツイッターで気軽に連絡して下さい!