pw dev
pw dev日常的に使うコマンドです。開発ループはプロジェクトファイルで定義されるため、引数は 取りません。
起動時にすること
Section titled “起動時にすること”devbox.jsonに宣言された Devbox サービスを起動するpw generateを実行するmigration.autoがfalseでなければ、未適用のマイグレーションを適用する- Tailwind が有効なら、スタイルシートをビルドしてウォッチャを起動する
dev.idp.enabledがtrueなら、開発用の認証プロバイダを起動するdev.otel.enabledがfalseでなければ、テレメトリビューアを起動するdev.logs.enabledがfalseでなければ、ローカルJSONL保存を準備するproject.mainをビルドして実行する
起動後は 0.5 秒ごとに監視対象を確認します。変更があれば、環境全体ではなく、その
ファイルに関係するステップだけを繰り返します。再起動したアプリケーションは
設定サマリを出力し直しません。
設定が変わらなかった再起動は reloaded とだけ表示し、変わった再起動は動いた行だけを
表示します。
監視する対象
Section titled “監視する対象”- プロジェクト自身の Go、
.pw.html、.pw.sqlのソース - マイグレーションディレクトリ
- Tailwind が有効な場合はその入力ファイル
popcornweb.tomlのdev.watch.includesに一致するもの
走査の範囲は [generate] の用途ではなくモジュール全体です。どの用途も生成に使わない
ファイルを含め、Go のソースはすべて再ビルドの入力だからです。.git、vendor、
node_modules、.devbox、public ツリーは常にスキップされます。
dev.watch.includes は、走査が届かない入力を加えるための相対 glob パターンです。
dev.watch.excludes はサブツリーをスキップします。大きな依存ツリーが走査をループ中で
最も遅いステップにしてしまうときに使います。どちらも絶対パスは拒否されます。
[dev.watch]includes = ["config.dev.toml", "assets/**/*.svg"]excludes = ["web/node_modules"]アプリケーションは server.port を bind しますが、開発ではそこに固執しません。別の
ターミナルでもう一つプロジェクトが動いている、正常に終わらなかったループがプロセスを
残している——そうしてポートが埋まっていたとき、実行は終わらずに次の空きポートへ移り、
どこへ移ったかを言います。
WARN the configured port could not be bound, so this development run moved to the next free one configured_port=8080 port=8081
listening on http://localhost:8081数字は 2 つ出ますが、意味は別です。設定ツリーの server.port は設定ファイルが要求した
値で、最後の listening 行は実際に応答するアドレスです。ブラウザで開くのは後者です。
コンソールがリンクするのはアプリケーション自身が申告したアドレスであってプロジェクト
ファイルの値ではないので、コンソールのアプリケーションリンクもシフトに追随します。
探索は設定されたポートから 10 個先で打ち切ります。そしてこれを行うのは開発時の実行だけ
です。APP_ENV=stg も APP_ENV=prod も、名前のついた環境はすべて設定どおりのポートを
bind し、できなければ失敗します。ヘルスチェックもリバースプロキシも運用者も、設定
ファイルが指すポートに来るからです。ただし APP_ENV 未設定は development に解決される
ので、変数を一度も設定していないデプロイもシフトしえます。警告が環境名を書くのはその
ためで、APP_ENV を設定することが厳密な bind を取り戻す方法です。
開発でもポートを固定したいとき——コールバック URL を登録済みの外部 OAuth プロバイダを
使うときなど——ポートが空いてさえいればシフトは起きないので、対処は塞いでいる相手を
止めることになります。pw doctor はループを起動する前に
server.port が埋まっていることを報告します。後から警告を読むより早く気づけます。
devbox.json に宣言されたサービス(既定では Valkey)は、Devbox のプロセスマネージャの
全画面 TUI を無効にした状態で動きます。ログは画面を覆い隠すのではなく、コード生成・
マイグレーション・アプリケーションの出力と同じストリームに、サービス名つきの 1 行ずつ
流れます。
[valkey ] 1:M 27 Jul 2026 23:02:32.103 * Ready to accept connections tcpサービスが不要なプロジェクトは devbox.json からパッケージを外してください。pw dev が
起動するのは Devbox が宣言したものだけです。
Tailwind
Section titled “Tailwind”開発中のウォッチャは assets.tailwind.minify の設定に関わらず、常に非 minify の
CSS を作ります。minify がループの中で最も遅い部分だからです。CSS ウォッチャが失敗しても
サーバーは停止しません。pw dev は動き続け、入力ファイルを直接監視する方式へ
フォールバックします。
tailwindcss は PATH 上にある必要があります。そのための devbox shell です。
スタイリングを参照。
マイグレーション
Section titled “マイグレーション”未適用のマイグレーションはアプリケーションの起動前に適用され、マイグレーション ディレクトリのファイルが変わったときにも適用されます。自分で制御したい場合は無効に できます。
[migration]auto = false開発用の認証プロバイダ
Section titled “開発用の認証プロバイダ”dev.idp.enabled が true のとき、pw dev はローカルの OpenID Provider を起動し、
issuer と資格情報をアプリケーションのプロセスに注入し、ループと一緒に停止します。
ユーザー定義ファイルを編集すると、再起動なしでリロードされます。
[dev.idp]enabled = trueユーザー定義ファイルの形式、claim、このプロバイダが実装するもの・しないものは 開発用の認証プロバイダを参照してください。
テレメトリビューア
Section titled “テレメトリビューア”pw dev はループバックの OpenTelemetry レシーバとブラウザ UI も起動し、標準の OTLP
環境変数でアプリケーションをそこへ向けます。既定で有効なので、コレクタを用意しなくても
トレースと関連づいたログレコードが読めます。
pw dev: telemetry viewer http://127.0.0.1:54321[dev.otel]enabled = trueOTEL_EXPORTER_OTLP_ENDPOINT がすでに設定されていれば何も起動せず、自前のコレクタに
任せます。開発用テレメトリビューアを参照して
ください。
ローカル構造化ログ
Section titled “ローカル構造化ログ”アプリケーションログは読みやすいテキストとしてターミナルへ出続けます。ビューアとは
独立して、pw dev は構造化形式も .log/pw-dev-*.jsonl へ保存します。一回の起動が
再ビルドをまたいで一つのファイルを所有し、ファイルは最初のレコードで初めて現れます。
[dev.logs]enabled = truedirectory = ".log"ディレクトリはプロジェクトからの相対パスで、自動削除されません。このスイッチを無効に すると、ターミナルと設定済みOTLP出力だけを残せます。スキーマとDuckDBクエリは テレメトリを参照してください。
pw dev はアプリケーションと並んで、固定のループバックポートでブラウザ向けの
コンソールを配信します。ループに必要なペインがここに集まります。プロジェクトの状態、
静的ファイル、データベースと宣言済みクエリ、テンプレートの storybook、pw doctor、
そして上記のテレメトリビューアです。
pw dev: console http://127.0.0.1:18081[dev.console]enabled = trueport = 18081ループの他の部分はここを通して読みます。そしてそのどれもリリースビルドには存在 しません。開発コンソールを参照してください。
テストデータエンドポイント
Section titled “テストデータエンドポイント”pw dev がビルドするアプリケーションは pwdev ビルドタグ付きで、開発環境ではその
バイナリが自身のリスナーで POST /_pw/test/seed/{dataset} と
GET /_pw/test/assert/{dataset} を、ループバックからの呼び出しに限って提供します。
ブラウザテストスイートはこれを使い、pw seed が読むのと同じ testdata/seed の
ファイルでデータベースを初期化・検証します。リリースビルドはエンドポイントのバイト列を
持ちません。E2E テストを参照してください。
Ctrl-C はループ全体をキャンセルし、アプリケーション、Tailwind のウォッチャ、
Devbox のサービスを停止します。ループを終わらせるのはこれだけです。アプリケーションが
自分で終了した場合——コンパイルエラーでも、パニックでも、正常終了でも——pw dev は
application exited: … と報告したうえで監視を続けます。動く状態から次の動く状態までの
間、プロジェクトはたいてい動かない状態にあるからです。次に保存した変更が、再ビルドと
再起動を行います。
