2026年11月12日、PythonだけでWebアプリの画面と裏側の処理を作れるフレームワークReflexの0.11.0が公開されました。10月27日の0.10.1から、およそ2週間での新しい版です。
GitHubのリリースノートには、互換性を壊す変更が7つ並んでいます。set型の状態変数の扱いが変わったほか、組み込みの管理画面が取り除かれました。
一方で、イベントハンドラーをawaitで呼べる機能など、嬉しい新機能も加わっています。今回は、0.10.1と0.11.0で同じコードを動かしながら、何が変わったのかを見ていきます。
まずはReflexとはどんなものか¶
最初に、Reflexを知らない方のために、どんなフレームワークなのかを簡単に紹介します。Reflexは、画面の見た目も、ボタンを押したときの処理も、すべてPythonで書けるWebアプリのフレームワークです。
書いたPythonのコードから、ブラウザで動く画面の部分を自動で作ってくれます。JavaScriptを書かずに、本格的なWebアプリを作りたい人に向いています。
状態とイベントハンドラー¶
Reflexでは、画面に表示するデータを、rx.Stateを継承したクラスの変数として持ちます。この変数を状態変数と呼び、値が変わると画面が自動で書き換わります。
ボタンが押されたときなどに状態変数を書き換える関数を、イベントハンドラーと呼びます。@rx.eventというデコレーターを付けて定義します。
import reflex as rx
class CartState(rx.State):
total: int = 0
tags: set[str] = {"新着", "セール"}
@rx.event
def add(self, amount: int):
self.total += amount
デコレーターの基本については、こちらで紹介しています。【関連記事】Pythonのデコレーターとは?
同じ仲間のツール¶
PythonだけでWebの画面を作れるツールは、ほかにもあります。最近のニュースで取り上げたものと、大まかに比べてみましょう。
| ツール | 特徴 |
|---|---|
| Streamlit | 上から順に書いたスクリプトが、そのまま画面になる |
| NiceGUI | 部品をwith文で並べ、イベントで直接書き換える |
| Reflex | 状態のクラスとイベントハンドラーで、画面と処理を分けて書く |
NiceGUIの最近の大きな変更は、こちらで紹介しました。【関連記事】NiceGUI 4.0がリリース
0.11で何が変わったのかを整理しよう¶
続いて、0.11.0の主な変更を表にまとめます。内容は、ReflexのGitHubにある0.11.0のリリースノートにもとづいています。
| 分類 | 主な変更 |
|---|---|
| 互換性を壊す変更 | set型とfrozenset型の状態変数が、集合専用のSetVarに |
| 互換性を壊す変更 | 組み込みの管理画面rx.AdminDashを削除 |
| 互換性を壊す変更 | deploy_urlの既定値がNoneになり、別のオリジンからの通信を既定で受け付けない |
| 互換性を壊す変更 | @rx.eventが、デコレートした関数ではなくEventHandlerを返す |
| 新機能 | イベントハンドラーを、別のハンドラーの中からawaitで呼べる |
| 新機能 | ブラウザの中だけで持つ状態rx.client_state |
| 新機能 | データベースの移行の道具Alembicとの連携 |
PyPIの記録によると、0.11.0が必要とするPythonは3.11以上です。0.11.0a1と0.11.0a2を経て公開されました。
set型の状態変数が、集合専用のSetVarに¶
まずは、初心者にも関係しそうな変更から見ていきましょう。リリースノートによると、set型とfrozenset型の状態変数は、これまでリストと同じArrayVarとして扱われていましたが、0.11.0からは集合専用のSetVarになりました。
0.10.1と0.11.0で確かめてみた¶
実際に、先ほどのCartStateのtagsが、どんな型として扱われるのかを確かめました。0.10.1と0.11.0を、それぞれ新しい仮想環境に入れ、手元のPython 3.11で実行した結果です。
| 確かめたこと | 0.10.1 | 0.11.0 |
|---|---|---|
| CartState.tagsの型 | ArrayCastedVar | SetCastedVar |
tags.contains("セール") |
使えた | 使えた |
tags.union({"限定"}) |
VarAttributeError | 使えた |
tags.to_array()[0] |
VarAttributeError | 使えた |
tags[0] |
使えた | 使えるが非推奨の警告 |
0.11.0では、和集合を作るunionなど、集合ならではの操作が使えるようになりました。リリースノートには、ほかにintersection、difference、issubsetなどの操作も並んでいます。
番号で取り出す書き方は非推奨に¶
一方で、tags[0]のように番号で取り出す書き方は、0.11.0では非推奨になりました。実際に書くと、次の警告が表示されました。
SetVar.__getitem__ has been deprecated in version 0.11.0. A set is not a sequence; call .to_array() first to use array operations. It will be completely removed in 1.0.
集合は順番を持たないので、番号で取り出すのは本来おかしい、という理由です。リリースノートでも、State.tags[0]をState.tags.to_array()[0]に書き換える例が示されています。
集合そのものの性質は、こちらで紹介しています。【関連記事】Pythonのsetとは?
組み込みの管理画面が取り除かれた¶
2つ目は、管理画面の変更です。これまでReflexには、データベースの中身を見たり書き換えたりできる管理画面rx.AdminDashが組み込まれていました。
リリースノートによると、0.11.0ではこれが取り除かれました。手元でrx.AdminDash()を呼ぶと、0.10.1では作成できましたが、0.11.0では次のエラーになりました。
AdminDashRemovedError: The built-in admin dashboard (rx.AdminDash, rx.App(admin_dash=...)) was removed. Mount starlette-admin yourself with api...
エラーの文面では、starlette-adminというライブラリを自分で組み込むよう案内されています。管理画面を使っていた方は、上げる前に移行の手順を確かめておく必要があります。
通信を受け付ける相手の既定が厳しくなった¶
3つ目は、本番で動かしている人に大事な変更です。リリースノートによると、deploy_urlという設定の既定値が、これまでのhttp://localhost:3000からNoneに変わりました。
その結果、本番のモードでこの設定がないときは、別のオリジンからの通信を受け付けなくなりました。オリジンとは、https://app.example.comのように、方式とドメインとポートを組み合わせたものです。
画面と裏側を別々に置いている場合¶
画面と裏側の処理を、別々のサーバーやCDNに置いている場合は、REFLEX_DEPLOY_URLという環境変数に、画面のURLを設定する必要があります。リリースノートでは、REFLEX_DEPLOY_URL=https://app.example.com reflex run --env prod --backend-onlyという例が示されています。
これまでは、どのオリジンからの通信も受け付ける状態でした。既定で安全な側に倒す変更ですが、上げたとたんに画面からつながらなくなる可能性があるので、注意してください。
イベントハンドラーをawaitで呼べるように¶
ここからは新機能です。リリースノートによると、イベントハンドラーの中で、別のイベントハンドラーをawaitで呼べるようになりました。
awaitで呼ぶと、同じ状態のまま、その場ですぐに実行され、戻り値も受け取れます。処理を小さなハンドラーに分けて、組み合わせて使いやすくなったわけです。
書き方の例¶
リリースノートの例を参考に、書き方の形を示します。add()を2回awaitで呼び、最後にお知らせを表示する、というものです。
手元の0.11.0では、このクラスがエラーなく定義できることまでを確かめました。画面を動かしての確認は、JavaScriptの実行環境が必要になるため、今回は行っていません。
class CartState(rx.State):
total: int = 0
@rx.event
def add(self, amount: int):
self.total += amount
return self.total
@rx.event
async def add_twice(self):
await type(self).add(1)
total = await type(self).add(1)
yield rx.toast(f"合計: {total}")
リリースノートによると、戻り値は、今のところ画面のほうには送られません。また、通常のイベントの外、たとえばAPIのルートの中でawaitするとエラーになると書かれています。
非同期処理の基本は、こちらで紹介しています。【関連記事】Pythonのasyncioとは?
そのほかの新機能と修正¶
リリースノートには、ほかにも多くの新機能が並んでいます。代表的なものを表にまとめます。
| 変更 | 中身 |
|---|---|
| rx.client_state | ブラウザの中だけで持つ状態。名前を付けると、どの部品からも読み書きできる |
| Alembicとの連携 | reflex db initなどのコマンドが、データベースの移行の道具Alembicを使うように |
| 処理の止まりすぎの警告 | 開発中、ハンドラーが0.2秒以上処理を止めると、場所を示して警告 |
| rx.foreachの警告 | 繰り返す部品に、安定したkeyを付けるよう警告 |
3つ目の警告は、初心者にとってありがたい機能です。重い処理をそのまま書いてしまい、画面が固まる原因を、開発中に教えてもらえます。
上げる前にやっておきたいこと¶
最後に、Reflexを0.11.0へ上げる前に確かめておきたいことを整理します。
| 順番 | 確認すること |
|---|---|
| 1 | set型の状態変数を、番号で取り出していないか |
| 2 | rx.AdminDashを使っていないか |
| 3 | 画面と裏側を別々に置いているなら、REFLEX_DEPLOY_URLを設定したか |
| 4 | @rx.eventの上に、ほかのデコレーターを重ねていないか |
4つ目について、リリースノートによると、@rx.eventの上に重ねたデコレーターは非推奨になり、1.0までは警告付きで動くそうです。ほかのデコレーターは、@rx.eventの下に書くよう案内されています。
私は10年ほどエンジニアとして開発に関わってきましたが、0.x系のフレームワークは、版が上がるたびに書き方が少しずつ変わるものだと感じています。警告が出たら、その版のうちに直しておくのが、1.0に向けた一番の近道です。
まとめ¶
2026年11月12日、Reflex 0.11.0が公開されました。set型の状態変数が集合専用のSetVarになり、組み込みの管理画面が取り除かれるなど、7つの互換性を壊す変更が入っています。
イベントハンドラーをawaitで呼べるようになり、処理を組み合わせやすくなりました。上げる前に、上の確認ポイントを一度見直してみてください。
ここまでお読みいただきありがとうございました。