Reflex 之外的三条路:Streamlit、NiceGUI、Gradio 该怎么选

老周在物流公司做数据。职位写着数据分析师,实际从写 SQL、清洗报关单到替财务拉月报都干。他只会 Python,前端经验停在大学时改过别人给的 HTML 模板。

去年十月,运营总监把他叫进会议室。客户问运费,销售现在都在微信里喊他,他手动跑一遍脚本,一天跑二十来次。总监想要一个网页:销售自己填重量、体积、目的地,页面直接出价格,最好还能导出报价单发给客户。

他回去搜了一晚上。”用纯 Python 写网页”这几个字把他带到 Reflex 官网(https://reflex.dev)。首页写得很动人,前后端都写 Python,不用碰 JavaScript。他 pip install reflex,reflex init,然后卡住了。初始化要拉前端依赖,公司网络对 npm 源不友好,第一次跑了二十分钟报错退出。第二天换了镜像源才算跑起来,localhost:3000 上出现了那个默认页面。他觉得自己成了。

真正的问题是第三天来的。他想在页面上放一个下拉框,选项从数据库读。文档说要把数据放进 State 类,用 computed var,还要注意 yield 和 async。照着抄能跑,改一个字段就报错,错误信息埋在前端编译日志里。一下午过去,他没弄明白为什么一个下拉框要写这么多东西。

那天晚上他停下来,问了自己一句更基本的话:我到底在做什么?

你交付的是一张页面,还是一个一直跑着的东西

这四个框架经常被放进同一张对比表,其实它们对”网页”这件事的理解完全不同。

Streamlit 的理解是:你有一个脚本,我给你一个网页外壳,每次有人动一下,我把你的脚本从头再跑一遍。Gradio 的理解是:你有一个函数,我给你一组输入框和一个输出框,把它包起来。NiceGUI 的理解是:你在后端建一棵界面对象树,浏览器只是这棵树的显示器。Reflex 的理解是:你用 Python 写组件,我把它编译成真正的前端应用,再配一个 Python 后端。

这四种理解,决定了后面几乎所有差异。

所以下面这张表我没有按性能、功能点去排,那些东西在内部工具这个场景里几乎不影响决策。我按真正会卡住人的五件事来排:授权能不能商用、部署要不要自己运维、前后端怎么分工、什么场景下最省事、第一版要花多久。

Streamlit Gradio NiceGUI Reflex
授权 Apache 2.0 Apache 2.0 MIT 框架 Apache 2.0,云服务另计费
部署方式 streamlit run,或托管在 Community Cloud python app.py;加 share=True 得到临时公网地址;或放 Hugging Face Spaces python main.py,可 Docker 部署,也能开成桌面窗口 reflex run 本地开发,reflex deploy 上官方云,或自行打包
前后端怎么分工 服务端把整个脚本从头跑一遍,返回页面 前端是现成组件,事件直接调用你写的函数 后端持有界面对象,事件通过 WebSocket 回到后端 Python 组件树编译成 React 前端,状态存在 Python 类里
适合的场景 报表、看板、参数调节页 模型试用、单函数演示、聊天界面 常驻操作台、仪器面板、需要实时刷新的小工具 多页面、要登录、要当产品长期维护的东西
上手成本 半天 一小时出 demo 一到三天 一周起,取决于要补多少前端概念

竖着看每一列会发现,它们不是同一类东西的四个候选。Streamlit 和 Gradio 卖的是最快看到结果,NiceGUI 卖的是控制得住,Reflex 卖的是最后能长成一个正经应用。选错的代价不在写不出来,在你写出来三个月之后发现改不动。

Streamlit:把脚本变成页面,代价是每次都从头跑

最常见的 Streamlit 用法,是运营每天早上要看退货率。写的人是个做商品的小姑娘,三十来行代码:读一张表,st.dataframe 展示,st.slider 选时间范围,st.bar_chart 画图。她没学过 Web,streamlit run 一敲,浏览器自己弹出来,老板当天就在用。

Streamlit 的模型简单到粗暴:整个脚本就是一个函数,任何交互都让它从头执行。这件事在只读场景里几乎是免费的。你不需要理解状态,不需要理解渲染,改一行代码存盘,页面自己刷新,官方 README 管这个叫 live editing。

麻烦也来自这里。脚本重跑意味着每次点击都要把上面的代码再走一遍。老周在 Streamlit 上做第一版报价工具时,读价目表的操作每点一次都要重跑,他只能加 @st.cache_data。再往后,他想加一个”生成报价单编号”的按钮,发现点完页面一重跑,计数器就归零,得把数字塞进 st.session_state。这些坑文档里都写了,但每一个都在提醒你:你在跟一个没有真正状态的模型较劲。

Streamlit 是 Apache 2.0 授权,官方提供 Community Cloud 免费托管(https://streamlit.io/cloud)。规模上它是这四个里社区最大的,GitHub 上数万星(https://github.com/streamlit/streamlit)。有个细节容易忽略:README 里写明他们已经暂停接受维护团队之外的 PR。这不影响你用,但说明迭代节奏由 Snowflake 的团队掌握,碰到深层 bug 时,能做的通常只有等,或者绕过去。

一句话概括,只要你的页面长得像一张报表加几个筛选器,Streamlit 是这四条路里最短的那条。一旦页面开始有流程、有前后依赖的动作,它会开始跟你作对。

Gradio:它解决的是”让人试一下”

Gradio 的场景从来不是内部系统,是模型演示。

一个做图像分割的工程师要给客户看效果,客户不信,非要自己试。他写了二十行:gr.Interface(fn=predict, inputs=gr.Image(), outputs=gr.Image()),然后 demo.launch(share=True)。几秒后终端打印出一个 *.gradio.live 的地址,发给客户,客户在浏览器里传自己的图,看到了结果。整个计算还在他那台笔记本上跑。

这个 share=True 是 Gradio 最锋利的地方,它把一个部署问题压缩成了一个参数。官方文档里列了一整套内置组件,覆盖文本、图像、音频、视频、数据框这些模型最常见的输入输出(https://www.gradio.app/docs)。要复杂布局就用 gr.Blocks,做对话就用 gr.ChatInterface。它还有 gradio_client,别人可以用代码直接调你的应用,把它当接口用。

托管上它有两条现成的路:临时链接,或者 Hugging Face Spaces 免费跑(https://huggingface.co/spaces)。对做研究的人这几乎是最优解,不用买服务器,不用配域名,也不用管 HTTPS 证书。

代价是它的界面基因。Gradio 的组件都是为”输入进去、结果出来”设计的。你让它做带侧边栏、多页面、有用户权限的管理后台,会一路别扭,也能做,但写出来的代码处处透着”这本来是给演示用的”。它用 Apache 2.0 授权,商用没有授权上的障碍。

如果需求里有”让外面的人试一下”,Gradio 就是答案,不用犹豫。如果需求是”我们自己人天天用”,它大概率不是。

NiceGUI:给一台一直开着的机器配个界面

这个框架在国内讨论得少,但它的定位清楚到你看一眼就知道它想服务谁。

做非标自动化的人常遇到这样的场面:一台贴标机卖到食品厂,机器旁边挂一块十五寸的触摸屏,操作工要在上面改速度、改间距、看今天的计数。原来那套界面是别人用 PyQt 写的,改一个参数就得重新打包,装到工控机上。换成 NiceGUI 之后,界面就是一个 Python 文件,进程跑在工控机里,屏幕那头用浏览器打开,或者直接开成 NiceGUI 的桌面窗口。要调参数,远程连上去改两行,重启进程,两分钟的事。

这是 NiceGUI 官方介绍里明确写的适用场景:微型 Web 应用、看板、机器人项目、智能家居(https://nicegui.io)。它的技术栈是 FastAPI 做后端,Vue 和 Quasar 做前端,中间用 socket.io 挂着一条长连接,README 里把这套结构写得很细。你写的 ui.button(...)、ui.label(...) 在后端是真正的对象,浏览器里的 DOM 只是它们的投影。

这个模型带来两个别处没有的能力。一是实时,它内置定时器,官方说最短可以十毫秒刷一次,接串口、接 PLC、接传感器这种数据一直在变的活它接得住。二是它能直接开成桌面窗口,不用浏览器,对没有网络的车间很实用。

它的作者在 README 里写过一段动机:他们喜欢 Streamlit,但觉得它在状态处理上”魔法太多”。这句话解释了 NiceGUI 的全部取舍。你拿到的是显式的对象和显式的事件绑定,一个按钮点击就是一个 Python 函数,函数里改了哪个对象,页面上就变哪一块。没有整页重跑,也就没有”我的变量怎么被重置了”这类问题。

代价在社区规模。NiceGUI 由德国一家叫 Zauberzeug 的公司维护,MIT 授权(https://github.com/zauberzeug/nicegui),体量比 Streamlit 和 Gradio 小一个量级。碰到冷门问题,你能依靠的是 GitHub issue 和它自带的示例目录。工程上该有的它都有,pytest 测试框架、Docker 镜像、conda 包都齐,只是周边插件远没有 Streamlit 那边热闹。

如果你的页面要一直开着、数据一直在动、用的人就站在设备旁边,NiceGUI 是这四个里最对口的。它不负责给你做网站,它负责给你做操作台。

Reflex:它想让你做出一个产品

回到老周。他后来还是回到了 Reflex,因为他想清楚了自己要的不是一张报表。

他那套东西最后长成了这样:销售登录,选客户,填参数,看历史报价,点确认生成 PDF,经理那边能看到所有报价的审批状态。这不是脚本,这是个小系统。Streamlit 能做,但每一页都要重新想状态放哪;Gradio 根本不适合;NiceGUI 能做,可登录、路由、多页面这些得他自己搭。

Reflex 站的位置就在这里。它把你的 Python 组件树编译成真正的前端应用。你写 rx.vstack、rx.input、rx.button,浏览器里跑的是一个正常前端,路由、静态资源、页面标题都在。后端那边,状态就是你定义的 rx.State 子类,字段是普通的 Python 类型标注,改了就同步到前端。

这个设计换来的上限很高。它不像 Streamlit 那样受限于重跑脚本,也不像 Gradio 那样被组件形状绑住。你要做二十个页面、要做权限、要自定义样式,它都接得住。

成本集中在前三天。reflex init 会装一堆前端工具链,网络不好就是老周第一次踩的那个坑。概念上也比别家多:State、event handler、computed var、组件编译、var 操作。你得接受”我在写一个前端框架的 Python 绑定”,而不是”我在写脚本”。

商业上它分得很清楚。框架本身是 Apache 2.0(https://github.com/reflex-dev/reflex),自己部署不花钱。官方云从免费档开始,免费只能挂一个应用、额度有限;Pro 二十五美元起,按月给的额度同时用于 AI 生成和托管(https://reflex.dev/pricing)。这个价对个人开发者不算便宜,对一家公司来说,给内部工具每月付二十五美元,通常比让老周多折腾两周划算。

当你的东西需要像个产品,有账号、有多页、要交给别人长期用,Reflex 多出来的复杂度是值得付的。如果只是一张报表,它就是杀鸡用牛刀,而且这把刀还挺难磨。

怎么选:看交互的形状,不看星数

写完上面这些,选择已经不太需要”决策”了。你只要回答一个问题:用户打开这个页面之后,会做几次动作,这些动作之间有没有依赖。

只有一次动作,填完看结果,那就是 Gradio。gr.Interface 就是为这个形状造的。

动作很多,但都是筛一下看一遍,彼此独立,那就用 Streamlit。它的重跑模型在只读场景下不产生任何成本,你省下的是全部的状态管理。

动作之间互相影响,页面要一直开着,数据自己会变,那就是 NiceGUI。你需要的是对象和事件,不是脚本。

动作组成一条流程,还要分人、分权限、分页面,那就是 Reflex。你要的其实是一个应用框架,只是碰巧用 Python 写。

星数在这个判断里几乎没用。Streamlit 的星最多,因为它门槛最低;Gradio 的星也多,因为做模型的人基数大。星数说明的是多少人曾经试过,不说明多少人还在用,更不说明它适合你的场景。

还有一个常被忽略的变量:这东西要活多久。一次性的分析页面,用 Streamlit 两天写完扔掉,是最优解。要活两年的内部系统,第一版慢一周换来的可维护性,会在第六个月全部还给你。老周第一版用 Streamlit 一周交付,财务用得很开心;三个月后需求变成”客户自己登录查报价”,他重写成了 Reflex。那三个月的代码基本没白写,因为业务逻辑是纯 Python 函数,搬过去只动了界面层。

这也是这四家共同的善意:业务代码都是普通 Python,界面层是可以换的。真正把你锁死的从来不是框架,是你把业务逻辑写进了界面回调里。

老周最后交了什么

他交了两个东西。

给财务的,是一个 Streamlit 页面,四十七行,读一张每天凌晨同步的表,选月份,出汇总,能下载 Excel。写完那天下午就上线,财务在群里发了个大拇指。

给销售的,是一个 Reflex 应用,登录、选客户、算价、出 PDF、留痕。做了三周,中间因为 npm 源的问题多花两天。上线之后销售不再在微信里喊他,改成在系统里提单,出错了他能查到是谁在哪一步改了什么。

他后来的说法是,一开始以为自己是在选框架,选到最后发现是在选这东西算谁的活。用 Streamlit 写的那个,是财务的活;用 Reflex 写的那个,是他的活。

这大概是这类选型里最实在的一条标准。你愿意为它调到晚上十点,就选那个能长成大东西的;你只想明天上午交差,就选那个半小时能跑起来的。

文中的老周是综合几类常见场景虚构的人物。涉及的授权、托管与定价信息分别来自各项目仓库与官网:https://github.com/reflex-dev/reflex、https://github.com/streamlit/streamlit、https://github.com/zauberzeug/nicegui、https://github.com/gradio-app/gradio。

延伸阅读

查看完整选型指南 →

Stay updated with our latest AI insights

Follow FuturePicker on Google
滚动至顶部