RORK LABEN
PRICING — 通常 Rork の階層が具体化しました。Junior が月額 $25 で100クレジット、Middle が $50 で250、Senior が $100 で500 という並びですCREDITS — 課金はメッセージ単位です。AI へ送るプロンプト1回が1クレジットで、画面をまるごと作る指示もボタンの色を変える指示も同じ1つを消費しますPRACTICE — ですので、細かい手直しを重ねるほどクレジットは早く減ります。要件をまとめて渡し、細部は手元のエディタで直す。この配分が実際のコストを大きく左右しますSTACK — 通常の Rork は Expo 経由の React Native を生成し、iOS と Android の両方に届きます。Rork Max は別製品で、ネイティブ Swift を書きますMAX — Max は月額 $200 から。クラウド上の Mac 群でコンパイルし、ブラウザにライブシミュレータを流し、2クリックで App Store へ公開します。Xcode は要りませんFOUNDATION — 土台のモデル層では Gemini 3.8 Flash が9月2日に一般提供、9月3日には GitHub Copilot でも使えるようになりました。導入価格の失効は12月31日ですPRICING — 通常 Rork の階層が具体化しました。Junior が月額 $25 で100クレジット、Middle が $50 で250、Senior が $100 で500 という並びですCREDITS — 課金はメッセージ単位です。AI へ送るプロンプト1回が1クレジットで、画面をまるごと作る指示もボタンの色を変える指示も同じ1つを消費しますPRACTICE — ですので、細かい手直しを重ねるほどクレジットは早く減ります。要件をまとめて渡し、細部は手元のエディタで直す。この配分が実際のコストを大きく左右しますSTACK — 通常の Rork は Expo 経由の React Native を生成し、iOS と Android の両方に届きます。Rork Max は別製品で、ネイティブ Swift を書きますMAX — Max は月額 $200 から。クラウド上の Mac 群でコンパイルし、ブラウザにライブシミュレータを流し、2クリックで App Store へ公開します。Xcode は要りませんFOUNDATION — 土台のモデル層では Gemini 3.8 Flash が9月2日に一般提供、9月3日には GitHub Copilot でも使えるようになりました。導入価格の失効は12月31日です
記事一覧/開発ツール
開発ツール/2026-09-06中級

eas env:list に --json がないと分かってから、環境変数の棚卸しを組み直しました

eas env:list に --json フラグは用意されていません。--format short の出力を安全に JSON へ変換し、三つの環境の抜けを一行で見つけるまでの手順を書き残します。

EAS8Expo201環境変数6CI7

preview ビルドを流す前に、EAS のダッシュボードを開いて環境変数を目で数えていた夜がありました。development・preview・production の三つに、プロジェクト単位とアカウント単位のスコープが重なります。画面を行き来しているうちに、どこまで確認し終えたのか分からなくなりました。

手で数えるのをやめようと思って eas env:list --json と打ちました。通りませんでした。

最初にお伝えしたいのは、これが打ち間違いではないということです。eas env:list--json は用意されておりません。同じところで手が止まった方に向けて、代わりに何を使うのか、そしてその出力をどう扱えば安全なのかを書き残します。

eas env:list が受け取るフラグは五つです

eas-cli v22.0.0 のソース(packages/eas-cli/src/commands/env/list.ts)で定義されているフラグは、次の五つです。

フラグ既定値役割
--environment(対話で選択)対象の環境。複数回の指定が可能
--formatshort出力形式。選択肢は longshort のみ
--scopeprojectプロジェクト単位かアカウント単位か
--include-sensitivefalsesensitive の値を伏せ字にせず表示
--include-file-contentfalseファイル型変数の中身を表示

引数として環境名をそのまま渡すこともできます。eas env:list production という書き方です。出力形式の選択肢は longshort の二つだけで、JSON はそこに含まれておりません。--json を足しても、定義されていないフラグとして扱われます。

ここで一つ、私が遠回りした点をお伝えします。ダッシュボードの表を見て「JSON で落とせるはずだ」と思い込み、フラグの一覧を確かめる前にオプション名を三つほど試しました。いま思えば、ソースの static override flags を先に読めば一分で済んだ話でした。

--format short の出力を、そのまま .env として使えない理由

--format shortNAME=value を一行ずつ出しますので、一見すると .env そのものに見えます。ただ、そのまま流用すると三か所で崩れます。

  • 先頭に環境名の見出し行が入ります(Environment: production の形)
  • 変数が一つも無い環境では No variables found for this environment. の一文だけが返ります
  • 変数名は太字で出力されますので、端末の条件によっては装飾の制御文字が混ざります

さらに厄介なのは、値そのものが読めない場合があることです。可視性が sensitive の変数は --include-sensitive を付けない限り伏せ字になり、secret の変数はそもそも EAS のサーバーから出てきません。伏せ字を値だと思って書き戻せば、伏せ字が本物の値を上書きします。

可視性の三段階と EXPO_PUBLIC_ 接頭辞の関係は別の軸の話ですので、そちらはEAS の secret は「アプリに入れない」設定ではありませんに譲ります。ここでは「読める値と読めない値が同じ行の形で並んで出てくる」という一点だけを押さえておければ十分です。

三十行ほどで JSON に変換します

見出し行を落とし、制御文字を除き、最初の = だけで分割します。伏せ字だけの値には readable: false を付けて、値ではなく印であることを残します。

#!/usr/bin/env python3
# eas env:list --format short --environment production | python3 eas_env_to_json.py production
import json
import re
import sys
 
ANSI = re.compile(r"\x1b\[[0-9;]*m")
HEADER = re.compile(r"^(Environment|Variables for this project|Account-wide variables)\b")
MASKED = re.compile(r"^\*+(\s*\(.*\))?$")
 
 
def parse(lines):
    out = []
    for raw in lines:
        line = ANSI.sub("", raw).rstrip("\n").strip()
        if not line or HEADER.match(line):
            continue
        if line.startswith("No variables found"):
            continue
        if "=" not in line:
            continue
        name, value = line.split("=", 1)          # 値に = が含まれても壊さない
        name = name.strip()
        if not re.fullmatch(r"[A-Za-z_][A-Za-z0-9_]*", name):
            continue                              # 装飾の残骸や説明行を捨てる
        out.append({
            "name": name,
            "value": value,
            "readable": not MASKED.match(value.strip()),
        })
    return out
 
 
if __name__ == "__main__":
    env = sys.argv[1] if len(sys.argv) > 1 else None
    json.dump(
        {"environment": env, "variables": parse(sys.stdin.readlines())},
        sys.stdout, ensure_ascii=False, indent=2,
    )
    print()

v22.0.0 のソースが出力する short 形式を再現した入力で動かした結果です。

{
  "environment": "production",
  "variables": [
    { "name": "APP_VARIANT", "value": "production", "readable": true },
    { "name": "EXPO_PUBLIC_API_URL", "value": "https://api.example.com", "readable": true },
    { "name": "SENTRY_AUTH_TOKEN", "value": "*****", "readable": false }
  ]
}

変数が一つも無い環境を渡しても、variables が空の配列になるだけで落ちません。Base64 のように値の中に = を含む文字列も、最初の = だけで分割していますので保たれます。

三つの環境を並べると、抜けが一行で見つかります

環境ごとに JSON を作ってから、次のスクリプトで並べます。

#!/usr/bin/env python3
# python3 eas_env_matrix.py env-development.json env-preview.json env-production.json
import json
import sys
 
envs, table = [], {}
for path in sys.argv[1:]:
    with open(path, encoding="utf-8") as f:
        data = json.load(f)
    env = data.get("environment") or path
    envs.append(env)
    for v in data["variables"]:
        table.setdefault(v["name"], {})[env] = "secret" if not v["readable"] else "ok"
 
missing = 0
print("NAME".ljust(28) + "".join(e.ljust(14) for e in envs))
for name in sorted(table):
    row = [table[name].get(e, "-") for e in envs]
    missing += row.count("-")
    print(name.ljust(28) + "".join(c.ljust(14) for c in row))
print(f"\nmissing cells: {missing}")
sys.exit(1 if missing else 0)      # 抜けがあれば CI を落とす

手元で動かすと、次のように出ます。

NAME                        development   preview       production
APP_VARIANT                 ok            ok            ok
EXPO_PUBLIC_API_URL         ok            ok            ok
SENTRY_AUTH_TOKEN           -             secret        secret
 
missing cells: 1

- が抜けです。この形にしてから、ダッシュボードで目を往復させる作業がなくなりました。終了コードを 1 で返していますので、ビルド前のジョブに挟んでおけば、設定を足し忘れたまま preview を流すことも防げます。

私が取り違えていたのは、読めない値と入っていない値の区別でした

最初のうち、私は伏せ字の行を「まだ入れていない変数」として数えていました。足りないと思って同じ名前を作り直し、production 側の値を上書きしかけたことがあります。原因は仕組みではなく、私の読み方でした。

伏せ字は「読めない」の印であって、「無い」の印ではありません。 この区別だけは、急いでいる日でも先に確かめるようにしています。

eas env:pull --environment production を使うときも同じ注意が要ります。このコマンドは .env.local を書き出しますが、secret の変数は値ではなくコメント行として出力されます。行の見た目だけで判断すると、サーバー側には確かに入っている値を、もう一度作り直してしまうのです。

環境変数の棚卸しは、SDK を上げる前にも効いてきます。ネイティブ側の設定がどこで消えるかを追う話はExpo SDK 57 に上げる前に、prebuild で消えるネイティブ変更を洗い出すにまとめてありますので、あわせてご覧ください。

まずは production を一度だけ JSON にして、日付を付けて手元に残してみてください。翌週の同じ出力と差分を取るだけで、いつ誰が何を足したのかが自分の手元に残ります。私はそこから始めました。

お読みいただきありがとうございました。

シェア

お読みいただきありがとうございます

Rork Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥2,480 の永久アクセス
メンバーシップを見る →

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

開発ツール2026-09-04
EAS の secret は「アプリに入れない」設定ではありません — 接頭辞と可視性を別々に決める
EXPO_PUBLIC_ の接頭辞は成果物に入るかを決め、EAS の可視性は誰が読めるかを決めます。二つを重ねたときに OTA 更新でだけ値が消える筋道と、出荷前に自分の手で確かめる手順をまとめました。
開発ツール2026-09-02
expo のパッチを1つ上げると、expo install の推奨が何個動くのかを数えました
expo install が推奨するバージョンは expo 本体のパッチ版に紐づいています。npm レジストリの実データで台帳の差分を数え、npm install が外す幅と、生成直後のプロジェクトに置く検査を示します。
開発ツール2026-07-30
Renovate が触ってよい依存と、触ってはいけない依存 — Expo SDK 57 の123パッケージを機械的に切り分ける
Rork 生成アプリに依存の自動更新を入れると、Expo が版を管理している123パッケージまで巻き込まれます。2026年7月30日時点の実測では、うち6件が npm の最新版へメジャー更新される差でした。除外リストを手で書かず SDK から機械生成する手順をまとめます。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →