Rork で作ったアプリの最初の10万円に到達すると、次の壁は「月次10万円を続ける」という課題になります。単発の売上を出すのと、毎月の売上を安定させるのは、求められるスキルセットが全く違います。私も最初の1本で10万円の単発を達成したときは喜びましたが、翌月に売上が急降下して現実を突きつけられました。ここではその後2年かけて月次売上を育ててきた経験から、Rork アプリの運用戦略を体系的にまとめていきます。
月次継続収益を作るために最も必要なのは、「作って終わり」から「運用が本番」への意識転換です。リリース時点では完成度60〜70%でも、運用の中で磨き上げていけば、最終的には100%の完成度を超えて「長く使われる資産」に育ちます。この意識転換を言語化するのが本記事の目的です。
単発収益と月次収益の構造的な違い
個人開発者の多くが、単発の売上は出せるのに月次が続かないという壁に当たります。その原因は、単発収益と月次収益が「時間軸」という根本から違うものだからです。単発はリリース直後のバズに依存しますが、月次は「ユーザーがアプリを使い続けてくれるか」という持続性の勝負になります。
単発収益を支える要素は、バズ・告知・ランキング入りといった一時的なドライバーです。公開直後の1〜2週間に強く働き、その後は減衰していきます。月次収益を支える要素は、継続率・リピート購入・月次サブスクリプション・検索流入の持続性といった、時間と共に厚みが増すドライバーです。両者は別物なので、単発を伸ばす打ち手と月次を伸ばす打ち手は重ならないことが多いです。
観点 単発収益 月次継続収益
主なドライバー バズ・告知・ランキング入り 継続率・更新・検索流入
効き始める時期 公開直後の1〜2週間 公開から2〜3ヶ月後
時間経過での変化 減衰する 積み上がる
主に見る数字 初週ダウンロード数・初週売上 コホート継続率・解約率・ARPU
手を止めたときの影響 ほぼ即座に売上が止まる 数ヶ月かけて緩やかに減る
時間の使い道 プロモーション 計測と改善の反復
この表で一番効くのは最下段です。単発は「動いた分だけ返ってくる」ので手応えがありますが、月次は「測って直す」という地味な作業に時間を吸われます。手応えの薄い作業を続けられるかどうかが、そのまま結果の差になっていると感じています。
この違いを理解せずに単発の打ち手ばかり繰り返すと、毎月リリース直後と同じようなマーケティング作業を続けることになり、消耗が激しくなります。月次を育てるには、単発の打ち手を一段落させて「運用の設計」に時間を振り分ける必要があります。運用設計に1ヶ月投資すれば、その後の6ヶ月は大幅に楽になるという感覚です。
Rork で作ったアプリは、開発サイクルが速いため運用フェーズでも優位性があります。軽いアップデートを月に2〜3回出せる開発体力を持っているなら、月次運用は他のツールで作ったアプリより格段に楽になります。この速度を運用の武器に変えていきましょう。
アップデート頻度と App Store ランキング
App Store のランキングアルゴリズムは複数の要素で構成されていますが、公開情報と複数のアプリを運営した経験から、アップデート頻度は明確に重要だと感じています。少なくとも月1回、可能なら月2回アップデートを出し続けるアプリは、同カテゴリ内での順位が落ちにくく、長期的な自然流入を確保しやすくなります。
アップデートの内容は毎回大きなものである必要はありません。「バグ修正とパフォーマンス改善」だけのアップデートでも、出さないよりは格段に効きます。私は Rork プロジェクトで、小規模な UI 改善・バグ修正・1つの新機能という組み合わせを標準化し、2週間に1本のペースで出せるようにしています。
アップデートを出すためのネタ切れは、やり方次第で簡単に防げます。ユーザーからのレビューコメント、App Store Connect のクラッシュレポート、Firebase Analytics のイベントログ、Rork のセッションデータ、これらを毎週1時間ずつ眺める時間を作ると、改善ネタは無限に出てきます。「気づく仕組み」さえ作っておけば、何をアップデートするかに迷うことはなくなります。
アップデート作業自体も標準化します。私の場合、ブランチ作成→機能実装→テスト→ビルド→App Store Connect 提出までを5時間以内に完了させるフローを組んでおり、週末の半日で完結するようになっています。Rork はビルドが早いので、この流れが回しやすいツールです。
リリースノートは営業資料として書く
リリースノートは、多くの開発者が軽視しがちな重要なポイントです。「バグ修正とパフォーマンス改善」とだけ書くのは、実装工数の節約にはなりますが、アップデートを楽しみにしているユーザーへのメッセージを捨てていることになります。リリースノートは、ユーザーとの月次の接点として最も読まれる場所なので、営業資料として設計する価値があります。
私が使っている書き方は、「今回のハイライト」を冒頭に1〜2行で書き、その後に箇条書きで変更点を並べる構成です。ハイライトには感情的な言葉を入れます。「ダーク画面がようやく完璧に!」「朝のアラーム音が選べるようになりました」のように、ユーザーが欲しがっていた変更を具体的に伝えます。
リリースノートを読んだユーザーが「よし、今日使ってみよう」と思うかどうかは、エンゲージメント復活の分水嶺です。休眠中のユーザーを戻す最も安価な方法は、魅力的なリリースノートを出すことだと私は思っています。アプリストアの更新通知、App Store 内の「アップデート」タブの表示、Rork 関連のコミュニティでの言及など、リリースノートは色々な場所に表示されるので、投資対効果が高い作業です。
オンボーディングを定期的に再設計する
オンボーディングは一度作って放置しがちですが、アプリが進化する以上、定期的に再設計する必要があります。機能が増えれば初回の説明ポイントも変わり、ユーザー層が変われば響く言葉も変わります。3〜6ヶ月に1回はオンボーディング全体を見直す時間を設けることをおすすめします。
良いオンボーディングの基準は、「初回起動から3分以内に、ユーザーがコア価値を体験できること」です。説明を増やすのではなく、説明を減らして「最初の成功体験」までの距離を短くする方向で改善します。Rork のコンポーネントベース設計は、オンボーディング画面の差し替えがしやすいので、この改善サイクルが回しやすいです。
オンボーディングの重要指標は、ファネル別の離脱率です。画面ごとに「何%のユーザーが次の画面に進むか」を Firebase Analytics や Mixpanel で計測し、離脱が大きい画面を特定します。私の経験では、3〜4画面以上のオンボーディングは離脱率が急増するので、2〜3画面に圧縮する方向で設計するのが安全です。
スキップボタンを用意するかどうかは、アプリの性質次第です。コア機能の体験が必須な瞑想・フィットネス系アプリならスキップ不可、カジュアルな機能が多いユーティリティ系ならスキップ可、といった使い分けをしています。スキップできないオンボーディングは丁寧な設計が必須なので、中途半端にやるなら最初からスキップ許可にする方が結果的に離脱は少なく済みます。
通知設計 — リエンゲージメントの主戦場
プッシュ通知は、月次収益を維持する上で最も強力なツールの一つです。しかし設計を間違えると「通知が鬱陶しいアプリ」として即アンインストールされる諸刃の剣でもあります。個人開発者として慎重に設計する必要があります。
通知の鉄則は「ユーザーが欲しい情報だけを送る」です。宣伝的な通知や機能紹介の通知は、開封率が下がるだけでなくブロックの原因になります。私は3種類だけに絞っています。行動リマインダー(ユーザーが設定した目標に基づくもの)、ソーシャル通知(友人の行動に関するもの、該当する場合)、コンテンツ更新通知(新しい情報が届いたとき)です。
通知の頻度は1日1回を上限にしています。ユーザーセグメント別に調整することもあり、アクティブユーザーには週3回、休眠ユーザーには2週間に1回、と異なるリズムで送信します。頻度の最適化は Firebase の A/B テストで回すと数ヶ月で明確な結果が出ます。
通知文のコピーも営業的に設計します。「通知が届いています」のような機械的な文ではなく、「昨日の続きから始められますよ」「3日間のストリークがもうすぐ達成できます」のような具体的な動機を与える文にします。Rork でアプリを作る際は、通知トリガーの設計段階で「どんな文言を送るか」までセットで設計するのがおすすめです。
import * as Notifications from "expo-notifications" ;
// アクティブユーザー向けの行動リマインダー例
async function scheduleStreakReminder ( userStreakCount : number ) {
const message =
userStreakCount >= 2
? `${ userStreakCount }日連続達成中!今日も続けましょう`
: "昨日の続きから3分で再開できます" ;
await Notifications. scheduleNotificationAsync ({
content: {
title: "今日の一歩" ,
body: message,
data: { type: "streak-reminder" },
},
trigger: { hour: 8 , minute: 0 , repeats: true },
});
}
通知をタップした後の画面遷移も重要です。通知から開いたときに、通知内容と関係ない画面に飛ばされると、ユーザーの信頼が損なわれます。通知の種類ごとに最適な着地画面を指定するよう設計すると、復帰率が明確に上がります。
チャーン対策 — サブスクリプションの命綱
フリーミアムやサブスク型のアプリを運営するなら、チャーン対策は収益安定化の最重要課題です。新規獲得は時間もお金もかかりますが、既存ユーザーを引き留めるのは相対的にコストが低く、しかも影響が大きいです。月次チャーン率を1ポイント下げるだけで、半年後の売上が10%以上変わることもあります。
チャーン対策の最優先事項は、解約フローの中で「もう一度考えてもらう機会」を提供することです。iOS のサブスクは Apple のサブスク管理画面から直接解約できますが、多くのアプリは解約直前にアプリ内で引き留めフローを挟んでいます。機能を使い切れていない場合は「この機能を試しましたか?」と提示し、価格が理由なら「学生割引にしませんか」「一時停止にしませんか」と提示する形です。
ここで一つ、私自身が長く誤解していた点を訂正させてください。iOS のアプリからは「今まさに解約しようとしている瞬間」を捕まえられません。自動更新の停止は設定アプリのサブスクリプション管理画面で行われ、その操作のコールバックがアプリ側に届く仕組みは用意されていないためです。以前の私はレシート更新の API を叩けば解約意図を検知できると考えていましたが、あれが返すのは購入履歴であって、ユーザーの意思決定の瞬間ではありませんでした。
つまり実際に作れるのは「解約を止めるフロー」ではなく、「自動更新がオフになった後、有効期限までの残り時間で打ち返すフロー」です。この違いは設計の重心を変えます。解約直前のモーダルを磨き込むより、オフを検知したあとの数日から数週間をどう使うかに時間を配分した方が、継続率に返ってきます。
もう一つ重要なのは、チャーンする前の兆候を検知することです。「過去7日間のアクティブ日数」が2日以下に減ったユーザー、「コア機能の利用頻度」が先月比で半減したユーザー、「通知の開封率」がゼロに近づいたユーザー、これらはチャーン予備軍です。早期発見して専用の通知やメールで呼び戻すことで、解約率を下げられます。
ユーザー別のコホート分析を習慣化すると、チャーン対策の精度は格段に上がります。登録月ごとに「6ヶ月後の継続率」を比較すると、どの施策が本当に効いているかが見えてきます。Firebase でも Mixpanel でもコホート分析は標準機能なので、毎月1回はこの画面を眺める習慣を作るのがおすすめです。
自動更新オフを検知して、残り期間で打ち返す
StoreKit 2 では購読の更新意思が Product.SubscriptionInfo.Status の更新情報に入っており、willAutoRenew が false になった時点で「期限切れが予約済み」の状態だと判断できます。Rork が生成するのは Expo ベースの React Native アプリなので、実務では RevenueCat の SDK 経由で同じ情報を読むことが多くなります。
import Purchases, { CustomerInfo } from "react-native-purchases" ;
type RenewalState = "active" | "cancel-pending" | "billing-issue" | "expired" ;
function classifyEntitlement ( info : CustomerInfo , key : string ) : RenewalState {
const e = info.entitlements.active[key];
if ( ! e) return "expired" ;
// 決済失敗と自発的な解約は原因が違うので先に分ける
if (e.billingIssueDetectedAt) return "billing-issue" ;
if ( ! e.willRenew) return "cancel-pending" ;
return "active" ;
}
Purchases. addCustomerInfoUpdateListener (( info ) => {
const state = classifyEntitlement (info, "pro" );
const expiresAt = info.entitlements.active[ "pro" ]?.expirationDate;
if (state === "cancel-pending" && expiresAt) {
scheduleWinBack ( new Date (expiresAt));
}
if (state === "billing-issue" ) {
showPaymentUpdatePrompt ();
}
});
分類を最初に置いているのには理由があります。cancel-pending と billing-issue では、打ち手が正反対だからです。前者は「価値が伝わっていない」問題なので、使われていない機能の提示や年額への切り替え提案が効きます。後者は「払う意思はあるのにカードが通っていない」問題なので、割引を出すのは的外れで、決済情報の更新導線を出すのが正解です。ここを一緒にした通知を送ると、どちらの層にも刺さらない文面になります。
打ち返しのタイミングは、有効期限からの逆算で決めます。
タイミング 状態 出すもの
検知した当日 cancel-pending 何も出さない(直後の接触は逆効果になりやすい)
検知から2〜3日後 cancel-pending 使われていない機能を1つだけ提示する
期限の3日前 cancel-pending 年額プランへの切り替え、または一時停止の案内
期限切れ直後 expired 無料機能で使い続けられることを伝える
期限切れから30日後 expired その間に入った新機能をまとめて伝える
検知当日に何も出さないのは、私の失敗から来ています。オフにした直後に引き留めを出したところ、通知そのものへの拒否反応が返ってきました。解約を決めた直後は、その決定が正しいと確認したい心理が働きます。少し置いてから、別の切り口で価値を出し直す方が受け取ってもらえます。
ペイウォールの見せ方そのものを触る場合は、Rork Max × RevenueCat Paywalls SDK で変わるペイウォール開発 にリモート更新と A/B テストの手順をまとめてあります。打ち返しの文面を毎回アプリ更新なしで差し替えられるようにしておくと、この領域の改善サイクルが一気に短くなります。
意図しない解約を先に潰す — 決済失敗と猶予期間
解約対策というと引き留めの話になりがちですが、順番としては先に潰すべきものがあります。ユーザーが解約を決めていないのに切れてしまう、決済失敗による離脱です。カードの有効期限切れ、限度額、発行会社側の判定など、こちらの製品品質とは関係のない理由で起きます。
Apple 側には、これを吸収するための仕組みが二つ用意されています。一つは請求リトライで、期限切れの後も一定期間、決済の再試行が続きます。もう一つが請求猶予期間(Billing Grace Period)で、リトライが続いている間もサービスを提供し続けられる設定です。
重要なのは、猶予期間が App Store Connect のサブスクリプショングループ側の設定であり、有効にしていないアプリが珍しくないという点です。設定期間の選択肢や既定値は変更されることがあるため、実際の値は App Store Connect の該当画面で確認してください。私が確認した時点では、月額以上のプランで短い期間と長い期間の2択という構成でした。
項目 猶予期間なし 猶予期間あり
決済失敗直後のアクセス 即座に停止する 継続して提供される
ユーザーの体感 突然使えなくなる 決済情報の更新を促されるだけ
復帰に必要な行動 再購読(購入フローをやり直す) カード情報の更新のみ
アプリ側の実装 — 猶予期間中も権限を有効に保つ判定が必要
表の最下段が実装の落とし穴です。猶予期間を有効にしても、アプリ側で「有効期限を過ぎたら権限なし」と単純に判定していると、払う意思のあるユーザーを自分で締め出してしまいます。RevenueCat のエンタイトルメントを使っている場合は猶予期間中も有効なものとして返ってきますが、レシートの日付を自前で見ている実装では、猶予期間の判定を明示的に足す必要があります。
自前でレシートの有効期限だけを見ている実装の場合、この判定漏れは本番運用に入ってから表面化します。決済失敗はステージングで再現しにくく、テストの網から漏れやすい領域です。権限判定のテストには猶予期間中の状態を明示的に作って通しておくことを推奨します。
この設定を先に勧めるのは、実装コストがほぼゼロで、対象が「すでに払う意思のあるユーザー」だからです。新規獲得の施策を一つ増やすより、こちらを確認する方が先に効く場面があります。
継続率を毎月同じ手順で測る
コホート分析を習慣にする、と書きましたが、手順を決めていないと毎月違う切り口を見ることになり、比較ができません。私は次の計算を固定して、月初に同じ数字を出すようにしています。
type Sub = { userId : string ; startedAt : Date ; canceledAt : Date | null };
function retentionByCohort ( subs : Sub [], monthsAfter : number , now = new Date ()) {
const buckets = new Map < string , { total : number ; retained : number }>();
for ( const s of subs) {
const cutoff = new Date (s.startedAt);
cutoff. setMonth (cutoff. getMonth () + monthsAfter);
// 観測期間が足りないコホートは除外する(ここが一番大事)
if (cutoff > now) continue ;
const y = s.startedAt. getFullYear ();
const m = String (s.startedAt. getMonth () + 1 ). padStart ( 2 , "0" );
const cohort = `${ y }-${ m }` ;
const b = buckets. get (cohort) ?? { total: 0 , retained: 0 };
b.total += 1 ;
if ( ! s.canceledAt || s.canceledAt > cutoff) b.retained += 1 ;
buckets. set (cohort, b);
}
return [ ... buckets]
. map (([ cohort , b ]) => ({ cohort, total: b.total, rate: b.retained / b.total }))
. sort (( a , b ) => a.cohort. localeCompare (b.cohort));
}
一番効いているのは、観測期間が足りないコホートを外す1行です。これを入れずに集計すると、直近に登録したユーザーはまだ解約する時間がないため継続率が高く出ます。私は以前これに引っかかり、直前に打った施策が効いたと判断して同じ方向に3ヶ月投資してしまいました。数字の絶対値ではなく、条件を揃えたコホート同士の差を見る、という原則に立ち返ってからは判断の精度が上がりました。
もう一つの実務上のコツは、サンプル数の少ないコホートを議論の材料にしないことです。登録者が数十人しかいない月の継続率は、数人の増減で数ポイント動きます。個人開発の規模だと、月ごとの細かい上下はほとんど誤差として扱った方が健全です。3ヶ月分をまとめて見て、傾向が同じ方向を向いているかだけを確認しています。
継続率をどこまで設計で作り込めるかについては、Rorkアプリのリテンション・LTV最大化 に初日からの導線設計を書いています。運用で測る話と、設計で作る話は表裏の関係なので、両方を行き来しながら進めるのが現実的です。
ラインナップ戦略 — 複数アプリで収益を分散する
1本のアプリで月次収益を維持し続けるのは、ジャンルや運にも左右されるため、個人開発者としては複数アプリ体制の方が安定します。3〜5本のアプリを運営し、それぞれが月3〜10万円を稼ぐ構成は、合計で月20〜50万円の収益を安定させる現実的な道です。
ラインナップを組むときに意識するのは、「同じジャンルで戦わない」ことです。瞑想アプリを3本出すより、瞑想・運動・学習の3つのジャンルで1本ずつ出す方が、ユーザー層もマーケティングチャネルも分散します。1ジャンルが検索アルゴリズムの変化で落ちても、他のジャンルが残るので収益が全滅することがありません。
ただしジャンル分散は「全く関連しないアプリを作る」という意味ではありません。自分が持っている世界観・デザイン哲学・開発スキルを再利用できる範囲でラインナップを組むと、制作効率が上がります。私の場合、「ミニマルで毎日使いたくなるアプリ」というテーマを全アプリに通し、デザインシステムとコード基盤を共有することで、2本目以降の制作時間を初回の60%程度に圧縮しています。
Rork のコンポーネント・テンプレートを再利用できる設計にしておくと、ラインナップ戦略が格段に楽になります。共通コンポーネントの抽出、Rork プロジェクト間での設計パターン共有、グラフィックアセットの共通化などを、2本目を作る段階で準備すると効果が大きいです。
新規アプリの追加ペースは、年に3〜5本が個人開発者の標準的な限界です。1本あたりの制作時間を2〜4週間で収められれば、運用と並行して新規アプリを増やせます。Rork のビルド速度を考えると、この目標は十分に現実的です。
アプリ間クロスプロモーションの設計
ラインナップが増えてくると、アプリ間のクロスプロモーションが新たな武器になります。既存アプリのユーザーベースを使って新規アプリのダウンロードを呼ぶのは、最もコストの低い流入チャネルです。個人開発者がラインナップを築く主な理由の一つがここにあります。
クロスプロモーションの設計で気をつけるのは、「押し付けにならないタイミング」です。アプリを開いてすぐに別のアプリの広告が出ると、体験を損ないます。私はユーザーがコア体験を完了した後、たとえば「今日の目標を達成しました」という画面の最下部に、小さな「こんなアプリも作っています」セクションを置く形にしています。
具体的な実装としては、フッターバナー・設定画面の「開発者の他のアプリ」セクション・達成画面の報酬ダイアログの3箇所にクロスプロモーション枠を置くのが効果が出やすいです。各枠のクリック率・コンバージョン率を計測し、効果の薄い枠は削除して別の場所に移動させます。
クロスプロモーションで大きく効くのは、「同じ開発者の信頼感」です。1つのアプリで満足した体験をしたユーザーは、同じ開発者の他のアプリにもポジティブな期待を持ちます。この期待に応え続けることで、ラインナップ全体のダウンロード率が底上げされます。
月次売上が停滞したときの3つの打ち手
月次売上が3〜6ヶ月停滞すると、多くの個人開発者は焦りや不安を感じ始めます。停滞を打破する打ち手はいくつかありますが、優先順位があります。以下の順に試すのが効率的です。
第1の打ち手は、ASO の再点検です。時間の経過と共に、App Store での検索傾向・競合の登場・キーワードの競争率は変わっていきます。半年以上放置されたメタデータは、高確率で改善余地があります。キーワード、アプリ名、サブタイトルを見直し、新しい検索傾向に合わせて再構成するだけで、ダウンロードが伸びることは珍しくありません。具体的な棚卸しの手順はRork で作ったアプリを App Store でヒットさせる にまとめています。
第2の打ち手は、ペイウォールまたは価格の再設計です。サブスク型アプリの場合、ペイウォールの見せ方や価格設定を3〜6ヶ月単位で見直すと、コンバージョン率が改善します。月額単価を据え置いて年額プランを追加する、無料トライアル期間を延ばす、プランの特典を再表現するなど、細かい打ち手を積み上げていきます。そもそも広告と課金のどちらを主軸にするかから見直す段階なら、Rork で作るモバイルアプリの収益化入門 で選び方を整理しています。
第3の打ち手は、新機能のローンチです。新しい価値を提供することで、既存ユーザーの満足度を上げ、新規ユーザーへの訴求力を高めます。ただし新機能開発には時間がかかるので、第1・第2の打ち手で効果が出ない場合の最後の手段として考えます。新機能は「ユーザーが本当に求めているもの」を選ばないと労力が無駄になるので、レビューやサポート問い合わせから選ぶのが安全です。
停滞期に避けたいのは、「新規アプリの開発に逃げる」パターンです。停滞している既存アプリを放置して新規アプリに力を入れると、運営アプリ全体の質が下がります。停滞したアプリをまず立て直すか、思い切って運用を終了する判断をするのが健全です。
今週から始める一つのアクション
月次収益の成長は、日々の小さな改善の積み重ねで作られます。今週1つだけアクションを決めて始めるなら、次のどれかがおすすめです。
運用中のアプリがあるなら、過去3ヶ月のレビューを全て読み返してください。星の数だけでなくコメントを一件ずつ読み、共通する不満点と要望を3つピックアップします。このリストが、次のアップデートの最優先項目になります。Claude や他のAIに要点サマリを作らせると30分で完結しますが、自分の目でも必ず通すことが大事です。
サブスク型アプリの場合は、App Store Connect を開いて請求猶予期間の設定を確認してください。有効になっていなければ、そこを有効にするのが今週の最短の打ち手です。コードを1行も書かずに、決済失敗で切れていたユーザーを取り戻せる可能性があります。
猶予期間がすでに有効なら、次は自動更新オフの検知を実装してください。前述の分類関数だけなら30分で入りますし、その後の打ち返しをどう設計するかという次の課題が、数字と一緒に見えてきます。
解約の瞬間を捕まえられると長く思い込んでいた分、この記事の該当箇所は誤ったまま公開されていました。訂正してお詫びいたします。同じ勘違いをしたまま実装に入る方が一人でも減れば嬉しく思います。
複数アプリを運営している方は、アプリ間のクロスプロモーションを1箇所追加してみてください。設定画面に「開発者の他のアプリ」セクションを1つ追加するだけで、月に数十〜数百のクロスダウンロードが発生します。
単発から月次への進化は、一度切り替わると後戻りしない感覚があります。アップデートの習慣、運用のリズム、ラインナップの分厚み、これらが重なって個人開発者の収益基盤を作ります。Rork がくれる開発速度を、新規アプリだけでなく既存アプリの運用にも使い続けていきましょう。