โจ Build iOS/macOS widgets without Swift. Just JavaScript, JSX, and creativity.
ScriptWidget is a powerful widget development platform that lets you create native iOS and macOS widgets using JavaScript and JSX-like syntax. No Swift required!
Think of it as "React Native for Widgets" - but simpler and more flexible.
| Feature | Description |
|---|---|
| ๐ฅ๏ธ Cross-Platform | One codebase for iOS and macOS widgets |
| ๐จ JSX Support | Declarative UI with JavaScript XML syntax |
| โก Native Performance | Compiled to native Swift/SwiftUI |
| ๐ง Rich APIs | Access device sensors, data sources, and more |
| ๐ฑ Interactive Widgets | Tap, swipe, and interact with widgets |
| ๐จ Custom Styling | Full control over appearance |
| ๐ฆ Template Gallery | Pre-built templates to get started |
| ๐ Live Preview | See changes instantly in Xcode |
# 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
โ โโโ Common/ # Script storage & package management
โ โโโ 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/ # React + CodeMirror editor frontend
โโโ 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>
);$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 14+ (for iOS 16+ / macOS 13+)
- macOS 13+ (Ventura or later)
- 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 run build- Run the app and create a new script from the in-app editor
- 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 script is a package stored under Scripts/<PackageName>/ (synced via iCloud /
the app group), with main.jsx as the entry point and an optional image/ folder.
- 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 |
console |
Logging (console.log / console.error) |
| Platform | Support | Notes |
|---|---|---|
| iOS | โ Full | iOS 16+ (iPhone, iPad) |
| macOS | โ Full | macOS 13+ (Mac) |
| watchOS | ๐ Planned | Future release |
| visionOS | ๐ Planned | Future release |
Contributions are welcome! Please read our Contributing Guide for details.
- ๐ Report bugs
- ๐ก Suggest features
- ๐ง Submit pull requests
- ๐ Write documentation
- ๐จ Share your widgets
ScriptWidget is released under the MIT License.
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

