ScriptWidget Studio auf dem Mac: Dateibaum, JSX-Editor und Live-Widget-Vorschau nebeneinander.

ScriptWidget: Native iOS- und macOS-Widgets mit JavaScript und JSX

ScriptWidget rendert einen JavaScript- und JSX-Baum als native WidgetKit-Views, sodass man Widgets für iPhone, iPad und Mac bauen kann, ohne Swift zu schreiben. Was es leistet, wie man es baut, wo es schwächelt und was die MIT-Lizenz erlaubt.

Die wichtigsten Punkte
  • ScriptWidget rendert einen JSX-Baum als native SwiftUI-Views, sodass eine JavaScript-Codebasis echte WidgetKit-Widgets für iPhone, iPad und Mac erzeugt – kein WebView, keine Bitmap.
  • ScriptWidget Studio auf dem Mac ergänzt CodeMirror-Editing mit Diagnosen, eine Laufzeitkonsole, Live-Vorschau für jede Widget-Familie und eine KI-Generierungsschleife gegen jedes OpenAI-kompatible Modell.
  • Ein Widget ist ein versioniertes Paket: widget.json erklärt Einstiegspunkt, Familien, Berechtigungen und erlaubte Netzwerk-Hosts, und die Community-Galerie installiert verifizierte Widgets und AI Skills mit einem Klick.
  • Die Hürde ist hoch und der Umfang schmal – Xcode 27 für den aktuellen Quellzweig, macOS 26 für Studio, iOS 16 für Widgets – und watchOS sowie visionOS stehen ausdrücklich nicht auf der Roadmap.

Widgets sind der eine Bereich der Apple-Plattformen, der noch immer davon ausgeht, dass man Swift schreibt. Eine WidgetKit-Erweiterung ist ein Swift-Target, in SwiftUI aufgebaut, und das ganze Werkzeug drumherum – Vorschauen, Timelines, App Intents – folgt aus dieser Annahme. ScriptWidget wettet anders: Man beschreibt das Widget als JSX-Baum in JavaScript, und die App rendert diesen Baum mit nativen SwiftUI-Views. Was am Ende auf dem Home-Bildschirm liegt, ist ein echtes Widget – kein WebView und kein Screenshot.

Es ist ein Open-Source-Projekt von Everett (everettjf), MIT-lizenziert, und mehr als nur eine Laufzeitumgebung: Eine Mac-Entwicklungsumgebung, ein Paketformat mit Berechtigungen, eine Community-Galerie und eine KI-gestützte Generierungsschleife sitzen auf derselben Engine. Die Projektseite verweist für die Nutzung der App auf eine App-Store-Version; das Repository ist die Plattform, und dieser Artikel handelt vom Repository.

Was es leistet

Die Kernidee passt in einen einzigen Aufruf. Man baut einen Baum aus vertrauten Elementen – vstack, hstack, text, image, gauge – übergibt ihn an $render, und ScriptWidget bildet jedes Element auf die passende SwiftUI-View ab. Gestaltet wird über Attribute, die wie SwiftUI-Modifier lesen: eine Schriftart, eine Farbe, ein Frame, eine Ausrichtung. Es gibt keine Swift-Datei, die mit dem JavaScript Schritt halten muss, und nichts, das bei einer Layout-Änderung neu generiert werden müsste.

Eine versionierte Laufzeit-API deckt ab, was ein Widget üblicherweise braucht: Speicher, Dateien, Netzwerk, Gerätezustand, Standort, Gesundheit und Systeminformationen, dazu Datenquellen. Auch Interaktion geht über den statischen Fall hinaus – Links, Buttons und Schalter, App Intents, Live Activities und Control Widgets –, sodass dieselbe Sprache, die das Widget zeichnet, auch sein Verhalten beim Tippen steuert.

Rund um die Laufzeit liegen die Teile, die daraus eine Plattform statt einer Bibliothek machen. Eine Vorlagengalerie liefert einen lauffähigen Ausgangspunkt, eine Community-Galerie installiert verifizierte Widgets und AI Skills mit einem Klick, und ein Datenquellen-Plugin-System verwandelt eine Fremd-API in einen deklarativen Konnektor, den man in einem Request-Lab auf dem Mac testen kann. Pakete sind versioniert, und ältere Skripte laufen weiter, statt gestrandet zu werden.

Wie man es installiert

Wer ScriptWidget einfach nutzen will, installiert die App über den offiziellen App-Store-Eintrag. Aus dem Quellcode baut man nur, wenn man an der Plattform selbst — Runtime, Studio oder Galerie — arbeiten will; dafür braucht man Xcode. Der aktuelle Entwicklungszweig verlangt Xcode 27, ScriptWidget Studio braucht macOS 26 und iOS-Widgets brauchen iOS 16 oder neuer. Eine Homebrew-Formel gibt es nicht.

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

Zwei Fähigkeiten müssen aktiviert sein, bevor die Skript-Ablage funktioniert: der iCloud.ScriptWidget-Container und die App-Gruppe group.everettjf.scriptwidget. Danach bauen und starten, und dann die mitgelieferten Beispielskripte unter Shared/ScriptWidgetRuntime/Resource/Script.bundle/ lesen, die in api-, component- und template-Ordner geteilt sind – eine brauchbare Karte dessen, was die Laufzeit bietet, bevor man etwas Eigenes schreibt.

Wie man es benutzt

ScriptWidget Studio ist die Mac-Antwort auf die Schleife aus Build und Vorschau, und hier wird der Großteil der Autorenarbeit entstehen. Das Fenster zeigt links einen Dateibaum, in der Mitte einen CodeMirror-6-Editor und rechts eine Vorschau: Schema-Vervollständigung, Diagnosen und Formatierung im Editor, darunter eine Laufzeitkonsole mit Zeitinformationen, und Live-Vorschau für eine Widget-Familie oder alle gleichzeitig. Ein Konfigurationspanel bearbeitet widget.json – Familien, Berechtigungen, Netzwerkdomänen, Plugins, Vorschauparameter –, sodass das Manifest nicht von Hand geschrieben werden muss.

Der Leitfaden beim ersten Start lohnt sich auch dann, wenn man direkt zum eigenen Projekt will: Er baut ein vollständiges Tutorial-Widget und führt in etwa fünf Minuten vom Bearbeiten bis zum Hinzufügen auf den Schreibtisch. Danach ist die Schleife kurz – main.jsx schreiben, Vorschau ansehen, anpassen.

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

Die Laufzeit stellt ihre APIs als Globals mit Dollar-Präfix bereit, sodass der Weg vom Lesen zum Benutzen kurz ist. Storage ist der Teil, den man gesehen haben sollte, weil er zeigt, wie ein Widget Zustand über Aktualisierungen hinweg hält:

$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>
);

Die Screenshots

Das Projekt dokumentiert sich selbst visuell. Das Mac-Set zeigt Studio mit Dateibaum, JSX-Editor und Live-Vorschau nebeneinander – genau das Fenster, aus dem das Titelbild dieses Artikels gebaut ist –, dazu Seiten zur API-Oberfläche, zu den Komponenten und zur Vorlagengalerie. Das iOS-Set zeigt den Code-Editor auf dem Telefon, ein Widget auf dem Home-Bildschirm und ein Marktplatz-Raster, das kleine, mittlere und große Widgets nebeneinanderlegt. Beide Sets liegen im Repository unter Resource/, die Bilder also im Quellbaum und nicht nur in einem Store-Eintrag.

Wie es unter der Haube funktioniert

Die Laufzeit besteht aus JavaScriptCore plus einer Babel-Transformation. Das JSX wird zu JavaScript kompiliert, das einen Baum aus Element-Objekten aufbaut; der native Host läuft diesen Baum ab und instanziiert die passenden SwiftUI-Views. Nichts davon ist ein WebView, und nichts wird nachträglich rasterisiert: Die View, die auf dem Home-Bildschirm landet, setzt WidgetKit aus echten SwiftUI-Primitiven zusammen. Genau das lässt sie wie ein Widget handeln statt wie ein Bild davon – Tint-Modi respektieren, sich an die Widget-Familie anpassen, am Rendering des Systems teilnehmen.

Dieser Unterschied ist der ganze Grund, warum das Projekt interessant ist. Ein JavaScript-getriebenes Widget, das über ein WebView oder eine statische Bitmap rendert, kann im Screenshot richtig aussehen und trotzdem jeden Test verfehlen, auf den es ankommt – Dark Mode, Tinted Mode, die breiteren Familien, Barrierefreiheit. JSX direkt zu SwiftUI zu rendern umgeht diese Problemklasse an der Wurzel, und es ist auch der Grund, warum dasselbe Skript unverändert auf iPhone, iPad und Mac läuft.

Pakete und die Galerie

Ein Widget ist ein Ordner unter Scripts/<PackageName>/, der über iCloud und die App-Gruppe synchronisiert. Neue Projekte nutzen Package 2.0, bei dem widget.json das maßgebliche Manifest ist: Es benennt den Einstiegspunkt, die unterstützten Familien, die angefragten Berechtigungen, die erreichbaren Netzwerk-Hosts und die verwendeten Datenquellen-Plugins. Das ist eine Sicherheitsform und keine Bequemlichkeit – ein Paket erklärt, was es braucht, und die Laufzeit kann es daran halten.

Die Community-Galerie baut auf demselben Format auf. Pakete sind verifiziert, die Installation ist ein Klick, und derselbe Katalog führt AI Skills – wiederverwendbare Anweisungssätze für die Generierungsschleife, die man importieren, verfassen, exportieren und teilen kann. Pakete, die älter als widget.json sind, bleiben lesbar und wandern beim Import und Export mit, statt zu brechen.

KI-unterstütztes Erstellen

Die KI-Funktionen sind kein an den Editor geschraubtes Chat-Fenster. Man richtet ein Anbieterprofil gegen ein OpenAI-kompatibles Modell ein und generiert, führt aus, diagnostiziert und verfeinert ein Widget direkt in Studio, wobei Konsole und Vorschau die Schleife speisen. Die Skills machen das wiederholbar: Statt in jedem Prompt die eigenen Konventionen neu zu erklären, hält man sie als geteilten Anweisungssatz, der mit dem Projekt mitreist.

Wo es schwächelt

Zuerst der Umfang, denn er ist Absicht: watchOS und visionOS stehen nicht auf der aktuellen Roadmap, und die README sagt das, statt es offenzulassen. Es ist also ein Werkzeug für Widgets auf iPhone, iPad und Mac und nicht für die gesamte Apple-Oberfläche. Studio ist zudem eine Mac-Anwendung, Autoren bedeutet also, am Mac zu sitzen, auch wenn das Ziel des Widgets ein Telefon oder Tablet ist.

Dann die Hürde. Der aktuelle Entwicklungszweig will Xcode 27, Studio will macOS 26, und Widgets wollen iOS 16 – nichts davon zielt auf einen älteren Rechner. Der Bau aus dem Quellcode bedeutet außerdem, ein Xcode-Projekt zu klonen und auszuführen statt einen Paketmanager-Befehl abzusetzen, und das Projekt gibt nichts anderes vor.

Zwei kleinere Einschränkungen. Der KI-Generierungspfad braucht einen eigenen OpenAI-kompatiblen Anbieter, das Feature ist also nur so gut wie das Modell und der Schlüssel, die man mitbringt, statt etwas, das die App liefert. Und die Galerie ist ebenso sehr ein Vertrauensmodell wie ein Feature: Verifiziert oder nicht, ein fremdes Widget zu installieren heißt, fremdes JavaScript auszuführen – genau deshalb erklärt Package 2.0 überhaupt Berechtigungen und Host-Allowlists.

Die Lizenz: Was du darfst

Der Quellcode steht unter der MIT-Lizenz, © Everett. Die praktische Lesart ist kurz und freizügig: kommerziell nutzen, verändern, weitergeben – auch innerhalb einer Closed-Source-App –, solange man Copyright-Hinweis und Lizenztext bei jedem wesentlichen kopierten Teil behält. Es gibt kein Copyleft und keine Pflicht, Änderungen zu veröffentlichen.

Eine Ausnahme gibt es, und sie ist wichtig, weil sie leicht übersehen wird. Die MIT-Lizenz deckt den Quellcode; der Name ScriptWidget, die Logos, die Screenshots und die App-Store-Marketingmaterialien sind ausgenommen und bleiben beim Autor. Man darf die Plattform forken und ausliefern, aber nicht als ScriptWidget ausgeben oder dafür deren Markenbilder verwenden.

Sollte man es bauen

Wer sich je ein Widget gewünscht hat, das kein App-Store-Entwickler für einen bauen würde, und sich in JavaScript wohlfühlt, findet hier den kürzesten Weg dorthin auf den Apple-Plattformen – und dass das Ergebnis wirklich nativ ist statt ein WebView im Widget-Gewand, macht den Umweg lohnenswert. Für Entwickler ist das interessante Artefakt die Laufzeit: ein JavaScriptCore-Host, der einen deklarativen Baum auf SwiftUI abbildet, verpackt in ein Paketformat, das über Berechtigungen nachdenkt – eine Form, die es wert ist, studiert zu werden, auch wenn man nie ein Widget ausliefert. Die Grenzen sind ehrlich und von vornherein benannt – kein watchOS oder visionOS, ein Mac-only-Studio, eine hohe Xcode-Hürde –, sodass die Entscheidung vor allem davon abhängt, auf welcher Seite man steht.

Projektübersicht

Lizenz
MIT
Plattform
iOS 16+ / macOS 26+ (Studio)
Sprache
JavaScript, JSX, Swift (SwiftUI-Laufzeit)
Geprüfte Version
main @ 2026-09-21

Installation

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

Lizenzübersicht

MIT ist eine freizügige Lizenz: Man darf den Code kommerziell und in Closed-Source-Apps nutzen, verändern und weitergeben, solange man Copyright-Hinweis und Lizenztext bei jedem wesentlichen kopierten Teil behält. Es gibt keine Gewährleistung. Name, Logos, Screenshots und App-Store-Marketingmaterialien sind von der MIT-Grant ausgenommen und bleiben beim Autor.