Website: https://xnu.app/scriptwidget/
Create native widgets for iPhone, iPad, and Mac with JavaScript, JSX, and AI
English | ็ฎไฝไธญๆ | Espaรฑol | ๆฅๆฌ่ช | ํ๊ตญ์ด | Franรงais | Deutsch | Portuguรชs | ะ ัััะบะธะน | ุงูุนุฑุจูุฉ
โจ Build iPhone, iPad, and Mac widgets in ScriptWidget Studioโwithout writing Swift.
ScriptWidget is an open-source widget development platform for building native WidgetKit experiences with JavaScript and JSX-like syntax. Write once, preview on Mac, and run the same package on iPhone, iPad, and Macโwithout requiring Swift for widget authoring.
It combines a JavaScriptCore runtime, native SwiftUI rendering, a desktop development environment, secure package sharing, AI-assisted generation, and a GitHub-backed community catalog.
| Feature | Description |
|---|---|
| ๐ฅ๏ธ Cross-Platform | One codebase for iOS and macOS widgets |
| ๐จ JSX Support | Declarative UI with JavaScript XML syntax |
| โก Native Rendering | JSX elements are rendered as native SwiftUI views |
| ๐ง Versioned Runtime API | Storage, files, networking, device, location, health, system, and data sources |
| ๐ฑ Interactive Widgets | Links, buttons, toggles, App Intents, Live Activities, and Control Widgets |
| ๐จ Custom Styling | Full control over appearance |
| ๐ฆ Template Gallery | Pre-built templates to get started |
| ๐ Community Gallery | Verified, one-click Widget and AI Skill installs |
| ๐งฐ ScriptWidget Studio | Build on Mac with CodeMirror, diagnostics, console, and multi-size preview |
| โจ AI Generation | Generate, run, diagnose, and refine widgets with an OpenAI-compatible model |
| ๐ง Skills 1.0 | Import, author, export, and share focused AI instructions |
| ๐ฆ Package 2.0 | Versioned widget.json, permissions, host allowlists, migration, and hardened imports |
| ๐ Data Source Plugins | Declarative third-party API connectors with a Mac request lab |
Studio is the primary place to build widgets:
- project file tree with multiple JavaScript/JSON files and package resources;
- CodeMirror 6 editing, schema completions, diagnostics, formatting, autosave, and crash recovery;
- live preview for one or every supported widget family, plus runtime console and timing information;
- Config panel for
widget.json, families, permissions, network domains, plugins, and preview parameters; - AI generation with provider profiles, iterative run/diagnose/refine, and reusable Skills;
- verified Widget & Skills Gallery and a Data Source Lab for testing plugin operations.
The first-launch guide can create a complete tutorial widget and walk a new user from editing through adding it to the desktop in about five minutes.
# Clone the repository
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- Select a scheme (
ScriptWidget/ScriptWidgetWidgetfor iOS,ScriptWidgetMacfor macOS) - Enable the
iCloud.ScriptWidgetcontainer andgroup.everettjf.scriptwidgetapp group so script storage works - Press
Cmd + Rto build and run - Browse the bundled example scripts under
Shared/ScriptWidgetRuntime/Resource/Script.bundle/(api/,component/,template/)
ScriptWidget/
โโโ Shared/
โ โโโ ScriptWidgetRuntime/ # Core runtime: JavaScriptCore host, JSXโSwiftUI
โ โโโ AI/ # Provider settings, agent loop, evals, Skills
โ โโโ Common/ # Script storage, Package 2.0, cache & imports
โ โโโ Gallery/ # Verified GitHub catalog, cache & installer
โ โโโ Plugin/ # Declarative Data Source Plugin runtime
โ โโโ Widget/Runtime/ # JS engine setup, Babel transform, execution
โ โโโ Widget/API/ # JS APIs ($device, $file, $storage, ...)
โ โโโ Widget/Component/ # Element โ SwiftUI view mapping
โ โโโ Resource/ # Babel bundle + bundled example scripts
โโโ iOS/
โ โโโ ScriptWidget/ # iOS app (editor, settings)
โ โโโ ScriptWidgetWidget/ # Widget, Live Activity, Control Widget
โ โโโ ScriptWidgetShare/ # Share extension
โโโ macOS/
โ โโโ ScriptWidgetMac/ # macOS app
โ โโโ ScriptWidgetMacWidget/ # macOS widget
โโโ Editor/editorfe/ # Vite + CodeMirror 6 editor frontend
โโโ Gallery/ # Curated Widget & Skills Gallery index
โโโ Tests/ # Shared runtime, execution, cache & security tests
โโโ docs/ # User, API, package, Skills & release documentation
โโโ Resource/ # Marketing assets, screenshots
โโโ README.md
A script's entry point is the $render(...) call, which takes a JSX tree built from
runtime tags (vstack, hstack, zstack, text, image, gauge, chart, ...).
$render(
<vstack frame="max">
<text font="title">Hello, ScriptWidget! ๐</text>
</vstack>
);const result = await fetch("https://jsonplaceholder.typicode.com/todos/1");
const model = JSON.parse(result);
$render(
<vstack>
<text font="title">{model.title}</text>
</vstack>
);Package 2.0 widgets using network access must declare the network permission and matching hosts in widget.json.
const weather = await $dataSource.request(
"app.scriptwidget.datasource.open-meteo",
"forecast",
{ latitude: "37.7749", longitude: "-122.4194" }
);
$render(
<vstack frame="max" padding="16">
<text font="caption">San Francisco</text>
<text font="largeTitle">{weather.current.temperature_2m}ยฐ</text>
</vstack>
);The package must declare the plugin identifier, network permission, and the plugin host. Plugins are declarative HTTPS request mappingsโnot executable native extensions.
$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>
);- Xcode 27+ for the current development branch
- macOS 26+ for ScriptWidget Studio
- iOS 16+ (for iOS widgets)
# Clone and setup
git clone https://github.com/everettjf/ScriptWidget.git
cd ScriptWidget
# Open in Xcode (pick the platform you want)
open iOS/ScriptWidget.xcodeproj # iOS
open macOS/ScriptWidgetMac.xcodeproj # macOS
# Build and run (Cmd + R)The editor frontend (React + CodeMirror) lives in Editor/editorfe:
cd Editor/editorfe
npm install
npm start # dev server at http://localhost:3000
npm test
npm run build
npm run release # rebuild and copy StudioEditor.bundle into both appsRun the same repository gates used by CI:
./Scripts/release-readiness.sh
./Scripts/ipad-icloud-tests.sh- Open ScriptWidget Studio on Mac (or ScriptWidget on iPhone/iPad) and create a script from a template, AI prompt, or blank project
- Write your widget in
main.jsxand call$render(...)with a JSX tree - Use the live preview to iterate, then add the widget from the Home Screen
Each widget is stored under Scripts/<PackageName>/ and synced through iCloud/app-group storage. New projects use Package 2.0:
My Widget/
โโโ widget.json
โโโ main.jsx
โโโ lib/
โ โโโ format.js
โโโ image/
โโโ background.png
widget.json is the authoritative, versioned manifest. It declares the entry point, supported families, permissions, allowed network hosts, and Data Source Plugins. Legacy main.jsx/meta.json packages remain readable and migrate during supported import/export flows.
Start with the documentation hub or build your first widget in ScriptWidget Studio.
- Entry point - call
$render(<tree/>)to draw the widget - Components -
vstack,hstack,zstack,text,image,gauge,chart, shapes, ... - Styling - element attributes such as
font,color,background,frame,padding - Widget sizes - read
$getenv("widget-size")(small / medium / large / accessoryโฆ) - Interactions - buttons and links via App Intents
| API | Description |
|---|---|
fetch() |
HTTP requests (fetch/$fetch) |
$storage |
Persisted key/value store (string & JSON) |
$file |
Read/write files in the script package |
$device |
Device info (model, battery, screen, dark mode, โฆ) |
$location |
Location & geocoding |
$health |
HealthKit data (steps, heart rate, โฆ) |
$system |
System info (timezone, app version, โฆ) |
$import |
Import another file from the package |
$dataSource |
Call a declared Data Source Plugin operation |
$runtime |
Runtime API version and enforced resource limits |
console |
Logging (console.log / console.error) |
The native JSX component switch is the runtime authority. Studio keeps static completion metadata in scriptWidgetAPI.js, checks it against the native switch, and generates the Runtime API reference from it.
Widget packages, Gallery content, Skills, and Data Source Plugins are treated as untrusted input:
- Package 2.0 rejects unknown fields and unsupported versions.
- Archive imports reject traversal, absolute paths, symlinks, encrypted entries, case collisions, malformed ZIP metadata, and oversized payloads.
- Package file access remains package-relative; storage is package-namespaced and bounded.
- Package 2.0 networking requires explicit permission and a matching host declaration; generic fetches are limited to public HTTP(S), while Data Source Plugins require HTTPS. Private/local hosts and oversized responses are rejected.
- Gallery files are restricted to the curated GitHub trust root and verified by exact byte count and SHA-256 before installation.
- Skills are prompt-only and cannot execute code, access secrets, or grant runtime permissions.
- Data Source Plugins are declarative request mappings and cannot load arbitrary native code.
See Package 2.0, modern WidgetKit features, Skills 1.0, Gallery, and Data Source Plugins for the complete contracts.
| Platform | Support | Notes |
|---|---|---|
| iOS | โ Full | iOS 16+ (iPhone, iPad) |
| macOS | โ Full | macOS 26+ (Mac) |
| watchOS | โ | Not in the current roadmap |
| visionOS | โ | Not in the current roadmap |
Contributions are welcome! Please read our Contributing Guide for details.
- ๐ Report bugs
- ๐ก Suggest features
- ๐ง Submit pull requests
- ๐ Write documentation
- ๐จ Share your widgets
- ๐ง Share focused AI Skills
See the public roadmap, governance model, and Gallery submission guide. Every pull request runs the same release-readiness checks used locally.
The source code in this repository is released under the MIT License.
The ScriptWidget name, logos, screenshots, and App Store marketing materials are not licensed under the MIT License. All rights to those brand and marketing assets are reserved by their respective owners.
Built with:
- JavaScriptCore - Apple's JavaScript engine
- SwiftUI - Modern UI framework
- Xcode Gen - Project generation
Inspired by:
- React - Component-based UI
- React Native - Mobile development
- WidgetKit - Apple's widget framework
ๆ้ฎ้ข๏ผๅป Issues ๆ้ฎ๏ผ
Made with โค๏ธ by Everett
Project Link: https://github.com/everettjf/ScriptWidget

