Mac 上的 ScriptWidget Studio:脚本文件树、JSX 编辑器与小组件实时预览并排显示。

ScriptWidget:用 JavaScript 和 JSX 构建原生 iOS 与 macOS 小组件

ScriptWidget 把 JavaScript 与 JSX 树渲染成原生的 WidgetKit 视图,让你不写 Swift 也能做 iPhone、iPad 和 Mac 的小组件。它能做什么、怎么构建、短板在哪,以及 MIT 许可允许你做什么。

要点摘要
  • ScriptWidget 把 JSX 树渲染成原生 SwiftUI 视图,一份 JavaScript 代码就能产出 iPhone、iPad 和 Mac 上真正的小组件,而不是网页视图或位图。
  • Mac 上的 ScriptWidget Studio 提供带诊断的 CodeMirror 编辑、运行时控制台、所有小组件族的实时预览,以及针对任意兼容 OpenAI 模型的 AI 生成闭环。
  • 小组件是带版本号的包:widget.json 声明入口、支持的族、权限和允许访问的网络主机,社区画廊一键安装经过验证的小组件与 AI Skill。
  • 门槛偏高、范围偏窄——当前源码分支要 Xcode 27,Studio 要 macOS 26,小组件要 iOS 16——而且 watchOS 与 visionOS 明确不在路线图上。

小组件是 Apple 平台上少数仍然默认你要写 Swift 的地方。一个 WidgetKit 扩展就是 Swift target,用 SwiftUI 布局,周边的工具——预览、时间线、App Intents——也都建立在这个前提上。ScriptWidget 押的是另一条路:你用 JavaScript 的 JSX 树描述小组件,应用把这棵树渲染成原生的 SwiftUI 视图。最终出现在主屏幕上的,是真正的小组件,不是网页视图,也不是一张截图。

这是 Everett(everettjf)的开源项目,MIT 许可,而且它不只是一个运行时:Mac 端的开发环境、带权限的包格式、社区画廊,以及 AI 辅助的生成闭环,都架在同一套引擎之上。项目官网指向 App Store 上的应用供日常使用;而这个仓库就是平台本身,本文讲的是这个仓库。

它能做什么

核心思路能装进一次调用里。你用熟悉的元素——vstack、hstack、text、image、gauge——搭出一棵树,交给 $render,ScriptWidget 就把每个元素映射到对应的 SwiftUI 视图。样式通过读起来像 SwiftUI 修饰符的属性来写:字体、颜色、frame、对齐。没有需要跟 JavaScript 保持同步的 Swift 文件,改了布局也没有东西要重新生成。

一套带版本号的运行时 API 覆盖了小组件通常需要的部分:存储、文件、网络、设备状态、定位、健康与系统信息,以及数据源。交互也不止于静态展示——链接、按钮与开关、App Intents、实时活动、控件小组件——也就是说,画小组件的那门语言同样能定义它被点按时的行为。

围绕运行时的那一圈,才是让它成为平台而非库的原因。模板画廊给你一个能跑起来的起点;社区画廊一键安装经过验证的小组件和 AI Skill;数据源插件体系把第三方 API 变成声明式连接器,还能在 Mac 上的请求实验室里试。包是带版本号的,旧脚本继续可用,而不是被丢下。

如何安装

如果只是想使用 ScriptWidget,请从官方 App Store 页面安装。只有在需要参与平台本身——运行时、Studio 或画廊——的开发时,才需要从源码构建,并且要使用 Xcode。当前开发分支要求 Xcode 27,ScriptWidget Studio 需要 macOS 26,iOS 小组件需要 iOS 16 或更高版本。没有 Homebrew formula。

git clone https://github.com/everettjf/ScriptWidget.git
cd ScriptWidget

# iOS app + widget + share extension
open iOS/ScriptWidget.xcodeproj

# macOS app + widget
open macOS/ScriptWidgetMac.xcodeproj

脚本存储要能工作,得先打开两项能力:iCloud.ScriptWidget 容器和 group.everettjf.scriptwidget App Group。之后构建运行,再读一读 Shared/ScriptWidgetRuntime/Resource/Script.bundle/ 下自带的示例脚本,它们按 api、component、template 分了目录,是你自己动手之前了解运行时都提供什么的好地图。

如何使用

ScriptWidget Studio 是针对「构建—预览」循环在 Mac 侧给出的答案,大部分编写工作都会在这里完成。窗口左边是文件树,中间是 CodeMirror 6 编辑器,右边是预览区:编辑器里有 schema 补全、诊断和格式化,下面有运行时控制台和耗时信息,预览可以只显示某一个小组件族,也可以全部一起显示。配置面板用来编辑 widget.json——支持的族、权限、网络域名、插件、预览参数——所以清单文件不必手写。

首次启动的引导值得跑一遍,即使你打算直接开自己的项目:它会生成一个完整的新手小组件,并用大约五分钟带你从编辑走到把它加到桌面上。之后的循环就很短了——写 main.jsx,预览,调整。

$render(
  <vstack frame="max">
    <text font="title">Hello, ScriptWidget! 👋</text>
  </vstack>
);

运行时把 API 暴露成带 $ 前缀的全局对象,所以从「读过」到「用上」的距离很短。最值得看一眼的是存储,因为它展示了小组件如何在两次刷新之间保留状态:

$storage.setString("greeting", "Hello ScriptWidget");
const greeting = $storage.getString("greeting");

$render(
  <vstack frame="max" background="#0f172a">
    <text font="caption" color="#94a3b8">Storage</text>
    <text font="title3" color="#e2e8f0">{greeting}</text>
  </vstack>
);

截图演示

这个项目用图像给自己做文档。Mac 那组截图把 Studio 的文件树、JSX 编辑器和实时预览并排放在一起——也正是本文封面图所取材的那个窗口——另外还有 API 范围、组件集和模板画廊的页面。iOS 那组则展示了手机上的代码编辑器、主屏幕上的小组件,以及把大中小三种尺寸并排铺开的市场网格。两组图都放在仓库的 Resource/ 下,所以这些图存在于源码树里,而不只是商店页面上。

底层是怎么实现的

运行时是 JavaScriptCore 加一层 Babel 转换。你的 JSX 会被编译成构建元素对象树的 JavaScript,原生宿主再遍历这棵树,实例化对应的 SwiftUI 视图。这里没有网页视图,也不是事后栅格化的图片:最终落到主屏幕上的视图,是 WidgetKit 用真正的 SwiftUI 原语组合出来的。正因如此,它才表现得像一个小组件,而不是小组件的图片——遵循着色模式、适配不同的族,并参与系统自己的渲染。

这个区别正是这个项目值得一写的原因。一个靠网页视图或静态位图渲染的、由 JavaScript 驱动的小组件,能在截图里看着没问题,却会在真正要紧的每一项检验里失败——深色模式、着色模式、更大的尺寸族、无障碍。把 JSX 直接渲染成 SwiftUI,从源头上绕开了这类问题;同一份脚本能在 iPhone、iPad 和 Mac 上原样运行,也是同一个道理。

包与画廊

一个小组件就是 Scripts/<PackageName>/ 下的一个文件夹,通过 iCloud 和 App Group 同步。新项目使用 Package 2.0,其中 widget.json 是权威清单:它声明入口文件、支持的族、请求的权限、允许访问的网络主机,以及用到的数据源插件。这是一种安全形态而非便利设施——包说明自己需要什么,运行时可以据此约束它。

社区画廊建立在同一套格式上。包经过验证,安装一键完成,同一个目录还收录 AI Skill——用于生成闭环的可复用指令集,可以导入、编写、导出和分享。早于 widget.json 的旧包仍然可读,在导入导出时迁移,而不是直接失效。

AI 辅助编写

AI 功能不是一个硬接在编辑器上的聊天窗口。你针对一个兼容 OpenAI 的模型配置服务商档案,然后在 Studio 里生成、运行、诊断和打磨小组件,控制台和预览都参与这个闭环。让事情可复用起来的是 Skill:与其在每个提示里重新解释你的习惯,不如把它们当作一套随项目走的共享指令。

短板在哪

先说范围,因为这是有意为之:watchOS 和 visionOS 不在当前的路线图上,README 也明说了,而不是含糊过去。所以它是为 iPhone、iPad 和 Mac 的小组件准备的工具,而不是覆盖整个 Apple 平台。Studio 本身也是 Mac 应用,也就是说哪怕小组件的目标是手机或平板,编写时你还是得坐在 Mac 前。

再说门槛。当前开发分支要 Xcode 27,Studio 要 macOS 26,小组件要 iOS 16——没有一处是针对旧机器的。从源码构建还意味着克隆并运行一个 Xcode 工程,而不是敲一条包管理器命令;项目也没有假装不是这样。

还有两点较小的提醒。AI 生成这条路需要你自己准备兼容 OpenAI 的服务商,所以这项功能的好坏取决于你带来的模型和密钥,而不是应用自带的什么。另外,画廊既是一项功能,也是一种信任模型:无论是否经过验证,装别人的小组件就是在跑别人的 JavaScript——这也正是 Package 2.0 要专门声明权限和主机白名单的原因。

许可:你能做什么

源代码采用 MIT 许可,© Everett。实际读起来很简短也很宽松:可以商用、可以修改、可以再分发——包括放进闭源应用——只要你在复制任何实质性部分时保留版权声明和许可文本。没有 copyleft,也没有公开你修改的义务。

有一处例外,值得说明,因为它很容易被忽略。MIT 覆盖的是源代码;ScriptWidget 的名称、标志、截图和 App Store 营销素材被排除在外,仍归作者所有。你可以 fork 这个平台并发布它,但不能把它当作 ScriptWidget 来用,也不能为此挪用它的品牌图像。

值得构建吗

如果你曾经想要一个「App Store 开发者不会替你做的」小组件,而你又熟悉 JavaScript,这是在 Apple 平台上走到那一步最短的路;而且结果是真正原生的,而不是披着小组件外衣的网页视图,这一点让这段绕路值得。对开发者来说,真正有意思的产物是那个运行时:一个把声明式树映射到 SwiftUI 的 JavaScriptCore 宿主,外面包着一套会考虑权限的包格式——即便你从不发布小组件,这也是值得研究的一种形态。它的边界很诚实,也一开始就说明白了——没有 watchOS 和 visionOS,Studio 仅限 Mac,Xcode 门槛偏高——所以做不做这个决定,多半取决于你站在这些边界的哪一侧。

项目概况

许可证
MIT
平台
iOS 16+ / macOS 26+(Studio)
开发语言
JavaScript、JSX、Swift(SwiftUI 运行时)
查看版本
main @ 2026-09-21

安装

# Open the App Store listing:
open https://apps.apple.com/us/app/scriptwidget/id1555600758

许可说明

MIT 是宽松许可:可以商用、可以放进闭源应用、可以修改和再分发,只要在复制任何实质性部分时保留版权声明与许可文本即可。没有担保。项目把名称、标志、截图和 App Store 营销素材排除在 MIT 授权之外,这些仍归作者所有。