一直停在 localhost 的小工具
你大概也有这么一两个项目,自己写的面板、内部用的 dashboard、随手做的一个工具页跑在本地。每次想用得先开终端敲一遍 npm run dev等它起来,再去浏览器新开一个标签。
app-it 想解决的就是这件事:把这种本地 web 项目变成 macOS 上一个能从 Dock 双击打开的 .app,有自己的图标、自己的窗口,点一下就运行,⌘Q 一下就退出。
app-it 不是 Anthropic 官方出的东西。它是一个独立开发者做的开源项目,README 里也专门标了「非官方社区项目,与 Anthropic、OpenAI 无关」。它只是做成了能装进 Claude Code 和 Codex 里用的插件形态,所以你用熟悉的 AI 助手就能驱动它。
它能做什么
它做的事很具体:读你磁盘上的项目判断这是个什么框架、用什么脚本启动、占哪个端口、有没有现成图标,然后选一种启动策略围着一个 WebKit 壳生成一个 macOS .app。
默认用的是原生 Swift 的 WKWebView,这样 Dock 上那个图标是「你的 App」,而不是某个浏览器,只有当项目确实要用到 Chrome 特有的能力时它才退回到 Chrome 的 --app 模式。
最终生成的是一个 universal 的 .app,arm64 和 x86_64 的 Mac 都能跑,也会顺手按你的素材生成一个 .icns 图标。

需要注意的是它面向的是本地使用场景,不是正式签名、公证后的方案。
下面这些,它明确不支持:
- • 它不是 Electron、Tauri,也不是把你的项目重写成原生应用。它只是给你现有的开发环境套了个壳,不替换、不迁移,也不往你的依赖里塞打包器。
- • 它不是一套签名分发系统。没有公证(notarization)、没有上架 App Store、没有自动更新、没有安装包。
- • 它只支持 macOS,这是作者刻意的选择。Windows 有一个单独的姊妹插件,但目前还是早期 beta。
动手前的准备
这一步是纯小白特别容易卡住的地方,单独拎出来讲。
你需要:
- 1. 一台 macOS 电脑。
- 2. 装好 Claude Code 或 Codex,因为插件是从它们的 marketplace 装的。
- 3. Xcode 命令行工具。这一条容易被忽略——app-it 生成原生壳要用到
swiftc编译器,它来自 Xcode 命令行工具。没装的话在终端跑一下:
xcode-select --install会弹窗让你确认,装完就有 swiftc 了。
- 4. 一个能在本地正常跑起来的 web 项目。Vite + React、SvelteKit、Astro、Next,或者有明确本地启动方式的静态项目都行。前提是它本来就能正常启动,app-it 不负责修复你的项目,它只负责套壳。
Chrome 不是必须的,只有当你的项目要走前面说的 Chrome fallback 时才用得上。
两行命令装插件
准备好了装插件。以 Claude Code 为例:
claude plugin marketplace add Christian-Katzmann/app-it
claude plugin install app-it@app-it如果你用的是 Codex:
codex plugin marketplace add Christian-Katzmann/app-it
codex plugin add app-it@app-it就这两行。装的是你 AI 助手里的一个插件,不是一个独立软件,所以你不会在「应用程序」里看到它。它的能力是在你跟 Claude / Codex 对话时被调用的。
核心实操:把项目变成 .app
打开终端,cd 进你那个 web 项目的目录,然后在 Claude Code 里直接发一句:
/app-it不想记命令也行,直接用大白话说就能触发,比如「把这个做成能从 Dock 打开的 app」「dockify this」「给它做个图标」。
接下来 app-it 会先「看一眼」你的项目:是什么框架、启动脚本是哪个、跑在哪个端口、有没有图标素材。看明白之后,它会往你项目里加一批文件,大致是这些:
- •
scripts/app-it.config.json——这个 app 的统一配置来源; - •
scripts/desktop-build.sh、desktop-install.sh、desktop-quit.sh、desktop-doctor.sh、desktop-verify.sh、wrapper.swift等一组脚本; - •
assets/下的图标文件; - •
desktop/<你的 App 名>.app/(这个会被 gitignore,每次 build 重新生成); - •
docs/desktop-launcher.md说明,以及一份app-it-report.md决策日志; - • 在
package.json里加desktop:build、desktop:install、desktop:quit、desktop:doctor、desktop:verify几个脚本。
有两个设计我觉得挺贴心的,一是改动以新增文件为主,并且可逆,它不碰你的业务代码,只会在必要时往 package.json 里追加桌面相关脚本;二是它会留一份 app-it-report.md,改了什么、为什么改、怎么撤回,全写在里面。
还有一点就是:app-it 在生成和校验的过程里可能会自己把你的 dev server 起一下、再停掉,用来确认这个壳能正常连上你的项目。
你要是看到终端里的服务被拉起来又关掉,那是正常流程不是出了 bug。
验证:双击、关窗、退出
生成完装好的 App 默认会落在 ~/Applications/App It/ 这个文件夹里(想换地方可以用 APP_IT_INSTALL_DIR 环境变量覆盖)。
一个小技巧:把这个文件夹拖到 Dock 右侧那一段,它会变成一个 Stack(堆栈)。以后你每用 app-it 包装一个项目,新 App 都会自动出现在这个 Stack 里,Dock 就慢慢「自己长出来」一排你自己的工具。

接着验证它是不是真的像个原生 App:
- • 双击图标:原生窗口打开,Dock 上是它自己的图标,不是浏览器的。
- • ⌘W 关窗口:窗口关了,但背后的 dev server 还温着。项目文档里给出的目标体验是约 250 毫秒级重新打开,实际速度还要看机器和项目本身。
- • ⌘Q 退出:这才是真正退出——它会把占用的端口一起释放掉,不留后台进程。
如果中间觉得哪里不对项目里几个脚本就是用来排查的,跑 npm run desktop:doctor 体检、npm run desktop:verify 校验,能帮你定位问题。
进阶
包装在线应用 / Claude Artifact:如果你要套的不是本地项目,而是一个已经部署的在线应用,或者一个发布出去的 Claude Artifact,app-it 支持给它配一个 external_url,每个用户在 App 窗口里用自己的账号登录,不共享任何密钥。
要注意:如果那个 Artifact 依赖 Claude 托管环境里的东西(比如 window.claude、window.storage),它就没法当成一个普通本地 React 项目来跑,得走在线包装这条路。
给成品减重:app-it 跑的是你项目的 dev server,开发阶段很合适,但 dev server 往往会占用不少内存。
按作者文档给出的量级,可能是 300 到 700 MB。等 App 真正做完了,其实不需要它了。作者还做了个更轻的伴侣插件 app-it-static,它直接 serve 你的构建产物(dist/、build/、out/ 这些),文档里给出的成品 App 量级大概是 15 MB。
还有个细节:默认的端口模式是 fallback,多个本地 App 会从首选端口往上扫,只有当你的 App 必须固定在某个 localhost 地址时——比如要用浏览器存储或者 OAuth 回调才需要手动改成 fixed。
几个边界
- • 它生成的是 ad-hoc 签名的本地 bundle。自己用没问题,但你要把它发给别人对方打开时大概率会撞上 Gatekeeper 的拦截提示,需要手动信任。它不能替代正经的签名分发,这点前面说过。
- • Xcode 命令行工具是硬前提。纯小白如果跳过了
xcode-select --install,到生成原生壳那步就会卡住,先把这个处理了。 - • 它的定位就是「自用 / 内部交付」的体验升级,本质是给 dev server 套了层体面的壳。
写在最后
app-it 解决的就是一直使用 localhost 的项目有个能双击、有图标、能退出的桌面入口。这个过程中不改代码,不上 Electron 对很多人来说够用了。
总结一份可复用的清单,下次照着走就行:
- 1.
xcode-select --install装好命令行工具; - 2. 两行命令装上 app-it 插件;
- 3. 进项目目录,
/app-it; - 4. 检查它加的文件和
app-it-report.md; - 5. 把
~/Applications/App It/拖进 Dock; - 6. 双击验证、⌘Q 退出确认端口释放;
- 7. 成品再换
app-it-static减重。
既然看到这里了,如果觉得不错的话随手点个赞、在看、转发三连吧,如果想第一时间收到推送,也可以给我个关注哦~
谢谢你看我的文章,我们下次再见。
夜雨聆风