機能
Seedに含まれるもの、まだないもの
Seedは無料でMITライセンスのSaaSスターターです。メールアドレス、Google、GitHubでのログイン、パスキー、マジックリンク、ゲストアカウント、2段階認証、ロール付きグループ、メンバー単位のStripe課金、リアルタイム更新、オフラインアプリ、管理画面、監視、そして任意で毎日の暗号化バックアップを備えています。以下の各セクションから、そのコードにリンクしています。
著者: Anton Shubin更新日:
Seedは今すぐ使えて、公開しながら開発中です。足りないものは、影響する機能の横に「まだないもの」と記し、issueがあればそのリンクも載せています。
面倒な部分は解決済み
グループと課金が最初から組み込まれたSaaSスターター
アカウント、グループ、お金。どのプロダクトでも最初の機能より前に必要で、しかも一番間違えやすい部分です。
現在使えるものCIでテスト済み。GoogleとGitHubでのログイン、Stripeには自分のキーが必要なため、デモではオフになっています。
アカウント
ログインは完成済み
ユーザーはメールアドレスとパスワードで登録し、コードでメールアドレスを確認します。忘れたパスワードの再設定、GoogleやGitHubでのログイン、パスキーでのログイン、そして登録も兼ねるメールのログインリンクにも対応。まずゲストアカウントでアプリを試して、あとからログイン方法を追加することもできます。認証アプリを使えば2段階認証(2FA)も有効にできます。ログイン中のデバイスはすべて一覧で確認でき、ほかのデバイスをログアウトさせることもできます。ログイン方法を変更するときは本人確認を求め、メールで通知します。
- パスワードはWeb CryptoのPBKDF2-SHA-256でハッシュ化(デフォルトで60万回)
- 署名付きのセッションCookieと、すべてのログインイベントの監査ログ
- 個人用APIトークンは鍵付きハッシュとしてのみ保存
- パスキー:保存するのは公開鍵だけで、ログインのチャレンジは1回限り有効
- マジックリンク:1つのリンクでログインも登録もでき、1回限り・15分間有効で、ハッシュとしてのみ保存
- ゲストアカウント(匿名ログイン):訪問者はログイン方法なしでワンクリックで始め、あとから同じアカウントにメールアドレスとパスワード、Google、GitHub、パスキーを追加できます
- パスワードの誤入力は、ネットワークアドレスをまたいでログイン名ごとに数え、上限を超えると短時間ロック

グループ
最初の1分から、ロール付きのグループ
すべてのアカウントに、登録時に個人用のグループが作られます。共有グループを作ってほかの人を招待し、閲覧者からオーナーまでのロールを割り当て、オーナー権限もワンステップで譲渡できます。削除したグループは30日以内なら復元でき、各グループにはアクティビティログが残ります。
- テナントの境界はグループだけ。個人のデータも共有のデータも同じチェックを通ります
- アプリでも、コードでも、このサイトでも、呼び名は「グループ」で統一
- 権限モデルは1つだけ。2つ目と同期させ続ける手間はありません
- 招待、ロール変更、オーナー権限の譲渡には、それぞれ専用のテスト

概要
グループごとの概要画面
任意の期間の主要な数値とグラフ。ウィジェットの表示・非表示や並び順は人ごとに変えられ、そのレイアウトはほかのデバイスにも引き継がれます。
- 各数値は前の期間と比較し、赤や緑で良し悪しを決めつけません
- 表示するのは件数だけ。メモの本文や人のランキングは出しません
- 読み込み、エラー、再試行はウィジェットごとに独立
- 新しい集約は独自のウィジェットを追加でき、管理画面にも表示されます
お金
Stripeによるメンバー単位の課金
ユーザーには料金表、制限付きの無料プラン、有料プランの14日間無料トライアルが表示されます。オーナーは招待の前にメンバーを1人増やすといくらかかるかを確認でき、カード決済が失敗したときは期日入りのわかりやすい通知が届きます。
- Stripe Checkoutとカスタマーポータル。プランの情報源はWebhookだけ
- メンバー数に連動する数量
- 支払い失敗後の猶予期間(デフォルトで7日間)
- プランの上限はアプリだけでなくサーバーでもチェック
- プランは1つのカタログファイルにまとまっていて、料金ページもそれを読み込みます
- Stripe以外の決済サービス

プライバシー
いつでも離れられるアカウント
ユーザーはプロフィールから自分のデータのコピーをダウンロードし、アカウントを削除できます。削除には7日間の猶予があります。既読の通知は90日後に削除されます。
- データのダウンロード:JSONとCSVファイルのZIPをバックグラウンドで作成し、7日間保管
- 削除は7日後に実行。もう一度ログインすると取り消されます
- 既読の通知、無効になった招待、古い監査イベントを毎晩クリーンアップ
エクスポート
データは自分のもの
どのグループもオープンなJSONファイルにエクスポートでき、あとから新しいグループとしてインポートできます。元のグループが上書きされることはありません。
- エクスポートはオーナーが行い、グループを作成できる人なら誰でもインポートできます
- 書き込む前にファイル全体をチェックし、1ステップでインポート
- メモとタグにはすべて新しいIDが振られるので、インポートしても既存のデータと衝突しません
- 各集約がファイル内の自分の担当部分を登録します
言語
最初から9言語に対応
アプリ、管理画面、このWebサイトは英語、ロシア語、スペイン語、ドイツ語、ポルトガル語 (ブラジル)、アラビア語、フランス語、日本語、簡体中国語に対応しています。言語はアプリ内で選べて、アカウントに保存されます。このWebサイトの各ページは、言語ごとに専用のアドレスを持っています。
- 言語ごとにTypeScriptのカタログが1つ。足りないメッセージや古くなったメッセージはテストがすべて指摘します
- 複数形、数値、日付はプラットフォーム標準のIntlで処理。i18nライブラリは不要です
- Webサイトの全ページにhreflangリンク、各言語を載せたサイトマップ
- アラビア語のページは右から左に表示
- メールは受信者の言語で届きます
必要になったときに、すぐ使える
リアルタイム、オフライン、バックグラウンド処理
難しいがゆえに多くのスターターが省いている部分です。ライブ更新、ネットワークなしで動くアプリ、そして失われてはならない処理。
現在使えるものオフラインでの書き込みはメモとタグに対応。そのほかのリストは、オフラインでも最後に表示した内容で開きます。
リアルタイム
再読み込みなしで変更が反映
メンバーの変更は、そのグループを開いているすべてのタブに表示されます。スリープから復帰したノートPCも、見逃した変更に追いつきます。
- 標準のWebSocketで、すべての変更に連番付き
- スリープから復帰したタブは再接続し、見逃した分を取得
- リアルタイムはオフにもできます。その場合アプリは一定間隔でポーリングし、同じように動きます


オフライン
ネットワークなしで開けるアプリ
アプリはネイティブアプリのようにインストールでき、ネットワークなしでも開けて、接続が戻るとためておいた変更を送信します。古くなった変更は解決すべき競合として表示し、黙って上書きすることはありません。
- 各リストのIndexedDBコピーと、冪等キー付きの書き込みキュー
- 競合ごとに「自分のバージョンを残す」か「サーバーのバージョンを使う」かを選択
- 設定1つでオフにでき、取り除くこともできます。フォルダを1つ削除し、用意されたチェックリストに従うだけです

キーボード
アプリと管理画面のキーボードショートカット
?キーを押すと、すべてのショートカットが表示されます。Nキーでどのページからでもその場でメモを追加でき、Gキーに続けて文字キーを押すと各セクションが開きます。入力欄に入力している間は、ショートカットは邪魔をしません。
- Ctrl K(Macでは⌘K)または/で検索を開く
- アプリごとに1つのリストがキーを割り当て、?のダイアログにも表示するので、効かないキーが表示されることはありません
- 1キーのショートカットはデバイスごとにオフにでき、その場合もCtrl KとEscは使えます
- 管理画面では、Gキーに続けて文字キーを押すと各モジュールが開きます
通知
アプリ、スマホ、デスクトップ、Telegramへの通知
招待されたとき、新しいロールを割り当てられたとき、グループを譲渡されたときに通知が届きます。アプリ内、スマホやデスクトップへのWebプッシュ、そして連携していればTelegramにも。
- 自分の鍵を使うWebプッシュ。鍵はタスク1つで作成:deno task vapid-key:create
- アプリ内の未読件数と「すべて既読にする」
- 各デバイスのプッシュ購読をプロフィールに一覧表示
- Telegramボットはトークンを設定するまでオフ。ワンタイムコードで連携し、プロダクト独自のコマンドは1ファイルで追加できます

バックグラウンド処理
クラッシュしても失われない処理
処理は実行前に保存されるので、サーバーが途中で再起動してもメールや通知はきちんと送られます。独自のジョブも、即時、あとで、またはスケジュールに沿って実行できます。
- 各コマンドは、変更と同じデータベーストランザクションでイベントを書き込みます
- ワーカーがそのアウトボックスを処理し、メール、プッシュ、ライブ更新を送信
- ジョブは1つの定義だけ:名前、ハンドラー、繰り返すならそのスケジュール
- 失敗した試行は間隔を広げながら再試行。オペレーターは管理画面ですべての実行を確認できます
あなたのプロダクト
既存の機能をコピーして、新しい機能を追加
メモ機能は、データベース、API、画面、オフライン、テストまで、すべての層がそろった完全な機能です。新しい機能は、各ファイルを順番に挙げたリストに沿って、それをファイルごとにコピーして作ります。
- どの機能も同じ形なので、コードを探しやすいまま保てます
- 各層には、一緒にコピーできる専用のテストがあります
- IDはすべて時系列順のUUID(バージョン7)
運用
動かして、見守って、ユーザーをサポートする
借りたサーバー1台、その動きを把握するためのツール、そしてオペレーターがプロダクトのユーザーを手助けするための管理画面。
現在使えるもの以下のモジュールはすべて現在提供中です。まだないものは各モジュールの下に記載しています。
サポート
オペレーターのための管理画面
オペレーターは名前やメールアドレスでユーザーを検索し、そのログイン方法、セッション、グループ、履歴を確認できます。同じ場所から、グループの管理、返金、ニュースレター購読者の管理、すべてのバックグラウンドジョブの確認、失敗したジョブの再実行、システムの状態確認ができます。 59秒の動画で見る.
- 専用のホストで動く独立したアプリで、セッションCookieも別
- ダッシュボードからAPIトークンまで、13個のモジュール
- リスクのある操作は事前に確認を求め、すべての操作を監査ログに記録
- ユーザーとしてログインし、その人と同じ画面を見る機能
デプロイ
サーバー1台、コマンド1つ
Seedは借りたLinuxサーバーならどこでも動き、開発でも本番でもDocker Composeを使います。複数のプロダクトで1台のサーバーを共有できます。
- 前段に証明書を自動取得するTraefik
- アプリと並んで動くPostgresとValkey
- S3互換のファイルストレージGarageに、メモの画像やPDF、プロフィール写真を保存。アップロードは署名付きリンク経由で、中身でチェックします。写真(HEICを含む)は、位置情報などのメタデータを取り除いた小さなAVIFとWebPに変換されます
- VictoriaMetrics、VictoriaLogs、Grafanaとアラート
- オプトインで毎日取れる、データベースの暗号化resticバックアップと、文書化された復元手順
- バージョンタグをプッシュすると、CIからリリースイメージを公開
- Traefik
- Postgres
- Valkey
- VictoriaMetrics
- VictoriaLogs
- Grafana
- Alertmanager
- Garage file store
- restic backups
Webサイト
自分用に手を加えられる公開Webサイト
このサイトのことです。高速で、サーバーでレンダリングされ、JavaScriptがオフでも使えます。料金ページ、法務ページ、ブログ、ニュースレター付き。
- サーバー側はFresh。すべての操作が本物のリンクかフォーム
- 料金はアプリのプランカタログから読み込み
- ダブルオプトイン、ワンクリック購読解除、受信者の言語で届くメールに対応したニュースレター
- 管理画面で書けるブログ。言語ごとの記事とその翻訳、トピック、RSSフィード、記事の構造化データに対応
- 連絡先リンクは管理画面で設定し、フッターと構造化データに表示
- ショップ用のオプションのカタログを管理画面で編集:写真、カラー、サイズ、サイズ表、売り切れのサイズを持つアイテムを、販売するすべての言語で。アイテムと共有先ごとに短いトラッキングリンクも作れます
- sitemap.xml、robots.txt、canonicalリンク、Open Graph画像
- 自分のUmamiを使ったCookie不要のアクセス解析(任意)。すべてのCTAにイベントを付け、管理画面の統計ページで、ソース別・アイテム別の訪問数と注文クリック数を確認できます
- すべてのページが9言語に対応し、それぞれ専用のアドレスとhreflangリンクを持ちます。法務ページは英語のままです
品質
大事なところをテスト
2026/10/16時点で、アプリのブラウザテストスイートが34個、加えてユニットテストと画面テストがあり、すべてCIで実行されます。すべての変更は、プルリクエストとレビューを経てからマージされます。
- Playwrightによるブラウザテストを、本物のAPIとデータベースに対して実行
- ユニットテストと画面テストは、テスト対象のコードのすぐ隣に
- Postgresに対する結合テスト
よくある質問
Seedでこんなことはできる?
SeedはVercelやサーバーレス関数で動きますか?
いいえ。Seedは、借りたLinuxサーバー1台の上でDocker Composeによる常駐コンテナとして動きます。APIがWebSocket接続を開いたままにし、ワーカーがキューを処理するためです。
SeedはNode.jsやBunで動きますか?
現時点では動きません。SeedのサーバーはDocker内のDeno 2で動き、タスクとテストにもDenoを使っています。コードはfetch、Request、Web CryptoなどのWeb標準の上に作られています。
Postgres以外のデータベースを使えますか?
いいえ。SeedはPostgresを前提に作られていて、マイグレーション、クエリ、結合テストもPostgresを想定しています。
Seedをモバイルアプリやデスクトップアプリとして配布できますか?
ストアで配布するアプリとしてはまだです。現在、Webアプリはスマホやデスクトップのブラウザからインストールでき、ネットワークなしでも開けます。Androidアプリとデスクトップアプリは計画中です。

