---
title: "GetX 之死 | 8 年从未用过，以后将不会再用"
source_name: "掘金本周最热"
original_url: "https://juejin.cn/post/7628535637260959770"
canonical_url: "https://www.traeai.com/articles/87210ea6-ac96-4f4b-8d45-82e2fd1187ac"
content_type: "article"
language: "中文"
score: 8.5
tags: ["Flutter","GetX","状态管理","软件架构","技术选型"]
published_at: "2026-04-14T23:55:31+00:00"
created_at: "2026-04-16T19:27:26.261356+00:00"
---

# GetX 之死 | 8 年从未用过，以后将不会再用

Canonical URL: https://www.traeai.com/articles/87210ea6-ac96-4f4b-8d45-82e2fd1187ac
Original source: https://juejin.cn/post/7628535637260959770

## Summary

GetX 因作者删库彻底消失，暴露了其单点维护、过度耦合和隐式依赖等架构风险。

## Key Takeaways

- GetX 全生态仓库被作者删除，项目失去源码与社区支持
- 过度集成导致高耦合，单一依赖失效影响整个应用
- 隐式依赖和绕过 context 带来可维护性与运行时风险

## Content

Title: GetX 之死 | 8 年从未用过，以后将不会再用

URL Source: http://juejin.cn/post/7628535637260959770

Published Time: 2026-04-15T07:55:31+08:00

Markdown Content:
#### 1.一个时代的句号

2026 年的某一天，当你打开 `https://github.com/jonataslaw/getx`，迎接你的不是那个熟悉的 10000+ star 的仓库，而是一个冰冷的 404 页面。

![Image 1: image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/b8ed026a97074c46a961ffe6efb8033b~tplv-k3u1fbpfcp-jj-mark:3024:0:0:0:q75.awebp#?w=1748&h=849&s=720039&e=png&b=f0d8ca)

不只是仓库。作者 jonataslaw（Jonny Borges）的整个 GitHub 主页也 404 了。`get_cli`、`get_server`、`get_storage`——整个 GetX 生态的所有仓库，一夜之间全部消失。

没有告别信，没有迁移公告，没有"项目已归档"的标注。一个曾经是 Flutter 社区最具争议、也最广泛使用的第三方包，就这样无声无息地消失了。

pub.dev 上的 `get` 包还在——因为 pub.dev 是独立托管的，不会因为 GitHub 删库而下架。你的项目今天还能 `flutter pub get`，还能编译，还能运行。但源码没了，issue 没了，786 个未关闭的 issue 没了，78 个待合并的 PR 没了，文档没了。

一个没有源码仓库的包，和一具没有灵魂的躯壳有什么区别？

* * *

#### 2.回顾：GetX 曾经有多火

在说"为什么不用"之前，先承认一个事实：GetX 确实火过。并且号称宇宙第一：

![Image 2: image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/af59ac8eaa1a4b5fb3c505875db07d67~tplv-k3u1fbpfcp-jj-mark:3024:0:0:0:q75.awebp#?w=1320&h=586&s=387597&e=png&b=fefdfd)

*   GitHub 10500+ stars，1600+ forks
*   pub.dev 上曾经是 likes 数最高的 Flutter 包之一
*   README 被翻译成十几种语言（日语、韩语、阿拉伯语、葡萄牙语……）
*   大量教程、视频、课程围绕 GetX 构建
*   在中文 Flutter 社区尤其流行，几乎每个技术群都有人推荐

它火是有原因的。看这段代码：

```
// 传统方式：定义 StatefulWidget，写 setState，管理生命周期
class CounterPage extends StatefulWidget {
  @override
  _CounterPageState createState() => _CounterPageState();
}

class _CounterPageState extends State<CounterPage> {
  int count = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(child: Text('$count')),
      floatingActionButton: FloatingActionButton(
        onPressed: () => setState(() => count++),
        child: Icon(Icons.add),
      ),
    );
  }
}
```

```
// GetX 方式：三行搞定
final count = 0.obs;

Obx(() => Text('$count'));

onPressed: () => count++;
```

对于刚入门 Flutter 的开发者来说，这种简洁性是致命的吸引力。"为什么要写那么多样板代码？GetX 三行就搞定了。"

但简洁和简单不是一回事。简洁是表面上代码少，简单是底层复杂度低。GetX 的代码少，但底层复杂度一点都不低——它只是把复杂度藏起来了。

* * *

#### 3.我为什么 8 年从未用过 GetX

从 2018 年开始写 Flutter，到现在 8 年了。期间无数次被推荐 GetX，无数次在技术群里看到"用 GetX 三行代码搞定"的安利。但我一次都没用过。甚至我的群聊公告里都写着:

> **本群禁止讨论 GetX,有任何问题可以向 GetX 官方提issue。**

不是因为我有先见之明，而是因为它违反了我认为正确的几个原则。

##### 原则一：不要把所有鸡蛋放在一个篮子里

GetX 管了你的状态、路由、依赖注入、国际化、主题、HTTP 请求、本地存储、表单验证……一个包解决所有问题，听起来很美。

但软件工程的基本常识是：**耦合越紧，风险越大。** 来看一个真实的对比：

```
# 方案 A：每层独立
dependencies:
  provider: ^6.0.0        # 状态管理
  go_router: ^14.0.0      # 路由
  dio: ^5.0.0             # 网络请求
  shared_preferences: ^2.0.0  # 本地存储
  intl: ^0.19.0           # 国际化

# 方案 B：全家桶
dependencies:
  get: ^4.7.3             # 状态 + 路由 + DI + 网络 + 存储 + 国际化 + ...
```

方案 A 看起来依赖多，但每个依赖都是独立的。`dio` 不维护了？换成 `http` 包，其他四个完全不受影响。路由库想升级？只改路由层，状态管理一行不用动。

方案 B 看起来清爽，只有一个依赖。但这个依赖出问题 = 所有东西出问题。

今天，这个"所有东西出问题"的场景真的发生了。

##### 原则二：隐式依赖是技术债的温床

GetX 最大的卖点之一是"不需要 context"。`Get.find()` 可以在代码的任何角落调用，不需要 Widget 树，不需要构造函数参数。

```
// GetX 的方式：在任何地方都能拿到任何东西
class OrderController extends GetxController {
  void submitOrder() {
    // 这三个依赖从哪来的？谁注册的？什么时候注册的？生命周期是什么？
    final cart = Get.find<CartController>();
    final auth = Get.find<AuthController>();
    final api = Get.find<ApiService>();
    // ...
  }
}
```

```
// 官方推荐的方式：依赖通过构造函数显式传入
class OrderViewModel extends ChangeNotifier {
  final CartRepository _cartRepository;
  final AuthRepository _authRepository;

  // 一眼就知道依赖了什么，测试时直接传 Fake
  OrderViewModel({
    required CartRepository cartRepository,
    required AuthRepository authRepository,
  }) : _cartRepository = cartRepository,
       _authRepository = authRepository;
}
```

写起来确实多了几行。但代价是什么？

| 维度 | `Get.find()` | 构造函数注入 |
| --- | --- | --- |
| 知道一个类依赖了什么 | 全局搜索才知道 | 看构造函数就知道 |
| 测试时 Mock 依赖 | 配置 GetX 全局容器 | 直接传 Fake 对象 |
| 删了一个注册 | 编译通过，运行时崩 | 编译直接报错 |
| 重构时追踪依赖 | 全局搜索 `Get.find<T>()` | IDE 的"Find Usages" |
| 循环依赖检测 | 运行时才发现 | 编译时就报错 |

这不是"风格偏好"，这是**编译时安全 vs 运行时崩溃**的根本差异。一个项目有 50 个 Controller，每个都用 `Get.find()` 拿依赖，你敢重构吗？

##### 原则三：不要依赖个人英雄主义

GetX 本质上是一个人的项目。jonataslaw 一个人写了状态管理、路由、依赖注入、HTTP 客户端、国际化、主题……一个人维护这么大的范围，质量和持续性都无法保证。

早在删库之前，信号就已经很明显了：

*   **2023 年 6 月**：社区开始问"5.0 什么时候发布？"（Issue #2797），至今没有正式版
*   **2023-2024 年**：超过 13 个月没有版本更新，停留在 4.6.5
*   **2025 年 1 月**：有人开了 Issue #3295 直接问"GetX 还活着吗？"
*   **786 个未关闭的 issue**，78 个待合并的 PR——一个人根本处理不过来

对比一下官方推荐的方案：

| 包 | 维护者 | 会因为一个人的决定消失吗？ |
| --- | --- | --- |
| `provider` | Flutter 官方团队 | 不会 |
| `go_router` | Flutter 官方团队 | 不会 |
| `ChangeNotifier` | Flutter 框架内置 | 不会 |
| `Navigator` | Flutter 框架内置 | 不会 |
| `flutter_bloc` | 社区团队（多人维护） | 极低概率 |
| `riverpod` | Remi Rousselet（provider 作者） | 低概率，且有社区 fork 能力 |
| **GetX** | **jonataslaw（一个人）** | **已经发生了** |

##### 原则四："不需要 context"不是优点，是危险信号

GetX 的宣传语之一是"不需要 context 就能导航、弹对话框、显示 SnackBar"。

```
// GetX：不需要 context
Get.to(HomePage());
Get.snackbar('标题', '内容');
Get.dialog(AlertDialog(...));
```

听起来很方便。但 `context` 在 Flutter 中不是累赘——它是 Widget 树的定位器，告诉框架"我在哪里"。绕过 context 意味着绕过 Flutter 的 Widget 生命周期管理，这会导致：

*   SnackBar 在页面已经销毁后还在显示
*   对话框在错误的路由上弹出
*   内存泄漏——Controller 没有跟随 Widget 生命周期释放

GetX 用全局状态和静态方法绕过了 Flutter 的设计，短期内写起来爽，长期维护时各种幽灵 Bug 让你怀疑人生。

* * *

#### 4.给正在用 GetX 的项目的建议

如果你的项目正在用 GetX，不要恐慌，但也不要心存侥幸。

**短期内你是安全的：**

*   pub.dev 上的包不会因为 GitHub 删库而消失
*   你的 `pubspec.lock` 锁定了版本，`flutter pub get` 还能正常工作
*   已编译的应用不受任何影响

**但定时炸弹已经埋下了：**

*   Flutter 下一个大版本更新（比如 Dart 4.0）可能导致 GetX 不兼容，没有人会修
*   发现 Bug 没有人修，发现安全漏洞没有人补
*   新入职的同事看到一个 404 的仓库链接，会对项目的技术选型产生严重怀疑

##### 迁移路径

不要一次性重写。逐层替换，每次只动一个模块，每次都跑测试：

```
第一步：路由（影响范围最小，最先动手）
  Get.toNamed('/home')  →  GoRouter 的声明式路由
  Get.back()            →  context.pop()
  GetPage              →  GoRoute

第二步：依赖注入（把隐式改成显式）
  Get.put(MyController())     →  ChangeNotifierProvider(create: (_) => MyViewModel())
  Get.find<MyController>()    →  context.read<MyViewModel>()
  Get.lazyPut(...)            →  Provider 的 lazy 默认行为

第三步：状态管理（工作量最大，收益也最大）
  GetxController + .obs + Obx  →  ChangeNotifier + Consumer / context.watch
  update()                     →  notifyListeners()
  GetBuilder                   →  Consumer

第四步：其他零散功能
  GetConnect        →  dio / http
  GetX 国际化       →  flutter_localizations + ARB 文件
  GetX 主题切换     →  ThemeData + ThemeMode
  Get.snackbar()    →  ScaffoldMessenger.of(context).showSnackBar()
  Get.dialog()      →  showDialog(context: context, ...)
```

每完成一步，跑一遍测试，确认没有回归。如果你的项目没有测试——这是另一个需要补的债，而且优先级比迁移 GetX 更高。

##### 迁移的工作量评估

| 项目规模 | GetX 使用深度 | 预估迁移时间 |
| --- | --- | --- |
| 小项目（10-20 个页面） | 只用了状态管理 | 1-2 周 |
| 中项目（30-50 个页面） | 状态 + 路由 + DI | 2-4 周 |
| 大项目（100+ 个页面） | 全家桶深度使用 | 1-3 个月 |

如果是大项目，建议新功能用新方案写，老功能逐步迁移，不要停下业务开发来专门做迁移。

#### 5.更深层的教训

GetX 之死不是个案。它揭示了开源生态中一个结构性的风险：**社区的繁荣可以掩盖项目的脆弱性。**

10000+ star、几十种语言的 README 翻译、数百个教程视频——这些都是社区繁荣的表现。但项目的健康度不取决于 star 数，而取决于：

*   核心维护者有几个人？（GetX：1 个）
*   有没有组织/公司背书？（GetX：没有）
*   issue 响应速度如何？（GetX：786 个未关闭）
*   版本发布频率如何？（GetX：5.0 难产三年）

下次选择一个第三方包时，不要只看 star 数和 likes。打开 GitHub 仓库，看看：

1.   **Contributors 页面**——核心贡献者超过 3 个人吗？
2.   **最近的 commit**——最后一次提交是什么时候？
3.   **Issue 列表**——维护者有在回复吗？
4.   **Release 历史**——版本发布有规律吗？

如果一个包只有一个核心维护者、半年没有 commit、几百个未关闭的 issue——不管它有多少 star，都要三思。

#### 5. 2026 年，Flutter 状态管理该怎么选

GetX 退场后，Flutter 状态管理的格局更清晰了：

| 方案 | 定位 | 适合谁 | 维护状况 |
| --- | --- | --- | --- |
| `provider` + `ChangeNotifier` | Flutter 官方推荐的入门方案 | 大多数项目 | 官方维护 |
| `Riverpod` | provider 的进化版，编译时安全 | 追求类型安全和可测试性的项目 | 社区活跃，多人维护 |
| `flutter_bloc` / `Cubit` | 企业级方案，严格的单向数据流 | 大型项目、需要审计追踪的场景 | 社区活跃，多人维护 |
| `setState` | 最简单的方式 | 临时状态、原型开发 | 框架内置，永远不会消失 |

没有 GetX。以后也不会有 GetX。

#### 6. 写在最后

8 年前我选择不用 GetX，不是因为预见了今天。是因为几个朴素的判断：

*   一个人维护的全家桶，风险太高
*   隐式依赖写起来爽，维护起来痛
*   绕过框架设计的"便利"，迟早要还债

今天这些判断被验证了。但我并不觉得高兴——毕竟有大量的项目和开发者受到了影响。那些用 GetX 写了几万行代码的团队，现在面对的是一个没有源码、没有维护者、没有未来的核心依赖。

如果你正在选择 Flutter 的技术栈，记住一条原则：

**每一层都应该可以独立替换。**

状态管理、路由、依赖注入、网络请求——每一层用独立的方案，每一层都有替代品。这样无论哪一层出问题，你都只需要换那一层，而不是重写整个应用。

这不是过度设计，这是基本的风险管理。

GetX 教会了我们：在开源世界里，**便利是借来的，风险是自己的。**

* * *

笔者目前正在公众号 **编程之王** 编写并发布《Flutter Agent Skills 全解析》系列，覆盖 Flutter 官方推荐的 22 个开发技能。如果你对 Flutter 官方推荐的架构、状态管理、测试等最佳实践感兴趣，欢迎关注。
