ブログ一覧に戻る
技術選定アーキテクチャスタートアップ

2人チームの技術選定 — niyaseの開発環境 2026年版

はじめに

niyase は2人チームで業務アプリを開発しています。勤怠・給与・会計・決算ができるアプリを、デスクトップ・クラウド・モバイルの3プラットフォームで提供しています。

少人数で開発していると、技術選定の1つ1つが重いです。「流行っているから」「みんな使っているから」では選べません。運用もデバッグも自分たちでやるので、理解できないものは入れられない。

この記事では、私たちが何を使っていて、なぜそれを選んだかを公開します。同じツールを使っている方には親和性を感じてもらえると思いますし、これから技術選定する方の参考になれば幸いです。

アーキテクチャ概要

Turborepo でモノレポを構成し、8つのアプリと5つの共有パッケージを管理しています。

アプリ

アプリ技術役割
desktopElectron + Electron Viteデスクトップ版。オフラインでも動作
cloudNext.js 16 (App Router)クラウド版(app.niyase.com)。チームでの共有・同期
mobileExpo SDK 54 (React Native)モバイル版
apiNestJSメイン API サーバー
wwwNext.js 16コーポレートサイト(www.niyase.com)
adminNext.js 16管理コンソール
estimate-pdf-generatorNestJS非同期 PDF 生成ワーカー
issue-estimatorNestJS + Anthropic SDKAI 見積もりワーカー

共有パッケージ

パッケージ役割
databaseDrizzle ORM スキーマ・マイグレーション
uiRadix UI + Tailwind CSS の共通コンポーネント
finance会計・XBRL ユーティリティ
eslint-config共有 ESLint ルール
typescript-config共有 TypeScript 設定

設計の軸はクラウドの便利さと、データ主権の両立です。クラウドでチーム間の共有・同期を便利に使いつつ、デスクトップ版ではオフラインでも全機能が動作します。ユーザーがクラウドに依存しなくても業務を続けられる選択肢を、技術で担保しています。

技術スタック一覧

言語・ランタイム

技術バージョン用途
TypeScript5.7 〜 5.9全レイヤーで統一
Node.jsv24 (Docker) / v20 (CI)サーバー・ビルド

全レイヤーを TypeScript で統一しています。フロントもバックもスキーマ定義も同じ言語なので、型を共有パッケージ経由で使い回せます。2人チームでは「言語の切り替えコスト」がそのまま生産性に直結するので、統一の効果は大きいです。

モノレポ

技術選定理由
TurborepoNX を検討したが壮大すぎた

NX は機能が豊富ですが、設定量も多く学習コストが高いと感じました。TypeScript に寄せるなら Turborepo で十分という判断です。ただし、今後 AI によるコード生成の比重が増えれば、TypeScript 縛りの意味が薄れるので、NX が候補に入る可能性はあります。

フロントエンド

技術用途
Next.js 16 (App Router, Turbopack)cloud / www / admin
Electron + Electron Vitedesktop
Expo SDK 54 (React Native)mobile
React 19全フロントエンドの基盤

3つのプラットフォーム(Web / デスクトップ / モバイル)を React ベースで揃えています。UI ライブラリやロジックの共有がしやすく、1つのプラットフォームで書いたコンポーネントを他に移植するコストが低い構成です。

バックエンド

技術用途
NestJSAPI サーバー、非同期ワーカー
Swagger / OpenAPIAPI ドキュメント自動生成
OrvalOpenAPI → TypeScript クライアント + React Query hooks を自動生成

NestJS の Module / Controller / Service の構造が、2人チームでも秩序を保つのに効いています。API 定義から Orval でフロント用のクライアントコードを自動生成しているので、API とフロントの型ずれが起きません。

データベース・ORM

技術用途
PostgreSQL 17メイン DB(Central DB + WS DB の分離構成)
PGliteデスクトップのローカル DB(WASM PostgreSQL)
SQLite (expo-sqlite)モバイルのローカル DB
Drizzle ORM全 DB 共通の ORM

なぜ Drizzle か。 Prisma は SQLite に十分対応していません。デスクトップではPGlite、モバイルでは SQLite を使うため、両方に対応できる Drizzle を選びました。SQL がそのまま見えるのでデバッグしやすく、マジックが少ない点も気に入っています。

なぜローカルDBを持つのか。 クラウドは便利ですが、クラウドにしかデータがない状態はリスクです。Google Workspace もエクセルダウンロードで離脱できる道を残しています。私たちも同じ考え方で、クラウドで便利に使ってもらいつつ、ユーザーがいつでもデータを手元に持てる設計にしています。

認証

技術用途
Firebase Auth全プラットフォーム共通の認証
Firebase Admin SDKAPI サーバーでのトークン検証
Firebase Emulatorローカル開発

なぜ Firebase か。 Google First の方針です。認証だけ Supabase、ストレージだけ AWS...と SaaS を分散させると、管理画面もドキュメントもバラバラになります。Google はかなりの領域をカバーしてくれるので、1つのエコシステムに寄せることで運用コストを下げています。管理画面の UI が使いやすいのも大きいです。

UI

技術用途
Tailwind CSSスタイリング
Radix UIヘッドレス UI コンポーネント
Lucide Reactアイコン
Sonner通知トースト
NativeWindモバイル向け Tailwind
CVA + clsxコンポーネントのバリアント管理

Radix UI はスタイルなしのヘッドレスコンポーネントなので、Tailwind CSS と組み合わせて自由にデザインできます。shadcn/ui のアプローチに近い構成です。

状態管理・API クライアント

技術用途
TanStack Queryサーバー状態管理
AxiosHTTP クライアント
OrvalOpenAPI からの自動生成

Redux や Zustand のようなグローバル状態管理ライブラリは使っていません。サーバー状態は TanStack Query、UI ローカル状態は React の useState / useReducer で十分回っています。

決済・メール

技術用途
Stripeサブスクリプション決済
Resendトランザクションメール

どちらも開発者体験が良く、API がシンプルです。

クラウドインフラ

技術用途
Google Cloud Storageファイルストレージ
Google Cloud Pub/Sub非同期メッセージング(PDF生成、AI見積もり)
Terraformインフラのコード管理
Docker Composeローカル開発環境

Google First の方針に従い、クラウドは GCP に寄せています。ローカル開発では fake-gcs-server(GCS エミュレータ)と Pub/Sub エミュレータを Docker Compose で起動し、本番と同じ構成で開発できるようにしています。

AI

技術用途
Anthropic Claude (SDK)AI 見積もり機能

issue-estimator というワーカーで、Pub/Sub 経由で受け取った案件データを Claude で分析し、見積もりを生成しています。

ドキュメント・PDF・OCR

技術用途
PDFKit / jsPDFPDF 生成(サーバー / デスクトップ)
Tesseract.jsOCR(デスクトップ)
XLSXExcel 入出力

業務アプリなので、帳票出力や書類読み取りの機能が必要です。これらはすべて JavaScript / TypeScript のライブラリで処理しており、外部サービスには依存していません。

テスト

技術用途
Vitestフロントエンド・デスクトップのテスト
JestAPI サーバーのテスト
Testing Libraryコンポーネントテスト
SupertestAPI の E2E テスト

CI/CD

技術用途
GitHub Actionsビルド・テスト・リリース
Electron Builderデスクトップアプリの署名・パッケージング(macOS / Windows / Linux)

3つの選定基準

技術を選ぶとき、私たちは3つの軸で判断しています。

1. クラウドの便利さと、データ主権の両立

クラウドでチームの共有・同期を便利に使ってほしい。でも、クラウドにロックインされてデータが人質になる状態は作りたくない。この2つを両立させるのが、私たちの設計方針です。

PGlite(WASM PostgreSQL)をデスクトップに組み込むことで、オフラインでも全機能が動作します。クラウドは「便利な同期・共有の手段」であって、「なければ業務が止まるもの」ではありません。

Google Workspace もエクセルダウンロードで離脱できる道を残しています。私たちも同じ考え方で、クラウドを積極的に使ってもらいつつ、ユーザーがいつでもデータを持ち出せることを保証しています。

2. Google First

SaaS の種類は厳選して絞りたいと考えています。認証は Firebase、ストレージは GCS、メッセージングは Pub/Sub、インフラは Cloud Run — Google のエコシステムでかなりの領域をカバーできます。

サービスごとに別のベンダーを使うと、管理画面・ドキュメント・課金がバラバラになり、2人チームでは運用が回りません。Google の管理画面は UI が使いやすく、1箇所で多くのことを把握できるのも選定理由の1つです。

3. 自分でコードを書く前提で選ぶ

マジックが多いツールは避けています。問題が起きたとき、中身が見えないと2人チームでは詰みます。

Drizzle ORM は SQL がそのまま見えます。Turborepo は NX より設定が少なく、やっていることが把握できます。この「理解できる範囲に収める」というのが、少人数チームの生存戦略だと思っています。

ただし、AI によるコード生成の比重が増えてくると、この判断基準は変わるかもしれません。AI が設定の複雑さを吸収してくれるなら、NX のような高機能ツールを使う合理性が出てきます。技術選定は固定するものではなく、チームの状況に合わせて見直すものだと考えています。

AI 開発ツール

開発には Claude Code を全面的に使っています。コード生成だけでなく、設計判断の壁打ち・リファクタリング・テスト生成まで、開発プロセスのほぼ全域で活用しています。

私たちが特に注力しているのは、日本語ドキュメントを充実させて AI へのコンテキスト供給源にするというアプローチです。これについては別の記事で詳しく書く予定です。

まとめ

2人チームの技術選定は「少なく・深く・自分で理解できるもの」が基本です。

  • クラウドの便利さ + データ主権 — 便利に使ってもらいつつ、ロックインしない
  • Google First — SaaS を分散させず、1つのエコシステムに寄せて運用コストを下げる
  • 理解できるものを選ぶ — マジックが少なく、問題が起きたとき自分で対処できること

このスタックに共感する方、あるいは「ここはこうした方がいい」という意見をお持ちの方がいれば、ぜひ話してみたいです。niyase では一緒に開発するメンバーを探しています。