Your own programs
Vom Skript zur nativen Executable — ein Klick. Der Empfänger installiert nichts.
Das ist das Feature, das OpticScript abhebt: Jedes Skript, das Sie
im Playground schreiben, ist einen Button-Klick von einer echten, in
sich geschlossenen .exe (oder Linux- / macOS-Binary) entfernt. Keine
Python-Runtime, kein Node-Setup, kein pip install, kein Docker-Image,
keine node_modules. Eine Datei. Versenden. Fertig.
$ ls -lh bin/
-rwxr-xr-x 1 mlc staff 16M 17. Mai 12:33 enhance
$ ./enhance --input portrait.jpg --output portrait_warm.jpg \
--brightness 1.15 --saturation 1.4 --vignette 0.5
✓ portrait_warm.jpg
Diese Binary ist ~16 MB groß, bettet die komplette Bild-Engine plus Ihr Skript ein und läuft in derselben nativen Geschwindigkeit wie der Playground selbst.
Im Playground — ein Klick
Den Make Exe-Button in der Editor-Toolbar klicken. Ein Dialog öffnet sich, fragt nach einem Tool-Namen, wählt standardmäßig Ihre aktuelle Plattform, und kurz darauf bekommen Sie den Pfad zur fertigen Binary. Der Build dauert Millisekunden, keine Minuten — die Engine liegt als vorgebauter Stub bereit; der Compiler hängt Ihr Skript als Blob an dessen Ende.
Dasselbe auf der Kommandozeile:
mlcos-compile-rs enhance.js
# → ./enhance (Linux/macOS)
# → ./enhance.exe (Windows)
Überall ausführbar — der Empfänger braucht kein OpticScript, keinen Playground, kein Rust, Go, Python oder sonstige Runtime. Die Binary ist vollständig eigenständig.
Was in der Binary landet
| Eingebettet | Warum das zählt |
|---|---|
| Die Bild-Engine (~16 MB) | Native Pixel-Ops, keine externe Runtime. |
| Ihr Skript | Als JS-Quelltext — --help liest es zurück, damit Sie auch später noch wissen, was das Tool tut. |
| Beide eingebauten Schriften (Inter + JetBrains Mono) | Text-Overlays / Wasserzeichen brauchen keine Font-Dateien. |
| Installierte Engine-Erweiterungen | Custom JS-Module (z.B. die cube-Extension) reisen automatisch mit. |
Was nicht eingebettet wird (bewusst extern):
- KI-Modellgewichte (GFPGAN, Real-ESRGAN). Tools, die diese aufrufen, laufen neben dem AI Tools Pack — dieselben Modelldateien wie im Playground.
Ihre Skript-Direktiven werden zu CLI-Flags
Jede //!INPUT:-, //!OUTPUT:- und //!PARAM:-Zeile am Skript-Anfang
wird zu einem getypten Kommandozeilen-Flag. Das Skript:
// enhance.js
//!INPUT: INPUT
//!OUTPUT: OUTPUT
//!PARAM: BRIGHTNESS:number=1.10,min=0.5,max=2.0
//!PARAM: SATURATION:number=1.20,min=0,max=3
//!PARAM: VIGNETTE:number=0.30,min=0,max=1
Engine.loadImage(INPUT)
.brightness(BRIGHTNESS)
.saturation(SATURATION)
.vignette(VIGNETTE)
.save(OUTPUT);
Kompiliert, dann --help:
$ ./enhance --help
enhance
Erstellt mit MLC OpticScript v2.1.3 · https://mlcgo.eu
Copyright (c) 2026 Michael Lechner · Elastic License 2.0
VERWENDUNG:
enhance --INPUT=<Pfad> --OUTPUT=<Pfad> --BRIGHTNESS=<Wert>
--SATURATION=<Wert> --VIGNETTE=<Wert>
EINGABEN:
--INPUT=<Pfad> (Bild laden)
AUSGABEN:
--OUTPUT=<Pfad> (Speicherziel; `-` für stdout)
PARAMETER:
--BRIGHTNESS=<Wert> (Standard: 1.10)
--SATURATION=<Wert> (Standard: 1.20)
--VIGNETTE=<Wert> (Standard: 0.30)
Die in //!PARAM: deklarierten min/max-Bereiche werden zur Laufzeit
geprüft — Werte außerhalb des Bereichs werden abgelehnt, bevor das
Skript überhaupt startet.
Einen ganzen Ordner verarbeiten — ohne Skriptänderung
Dieselbe Binary erledigt Batch-Verarbeitung. --INPUT auf einen Glob
und --OUTPUT auf ein Template setzen — die Engine bleibt über den
ganzen Loop "warm":
./enhance --INPUT='photos/*.jpg' --OUTPUT='enhanced/{stem}.png'
batch: 17 Datei(en) via --INPUT
✓ OUTPUT → enhanced/IMG_0001.png
✓ OUTPUT → enhanced/IMG_0002.png
…
| Eingabe-Muster | Beispiel |
|---|---|
| Glob | 'photos/*.jpg', '**/*.png' |
| Dateiliste (eine pro Zeile) | @todo.txt (#-Kommentare erlaubt) |
| Komma-Liste | a.png,b.png,c.png |
Ausgabe-Templates unterstützen die Platzhalter {stem} / {name} /
{ext} / {dir} / {idx} / {n}.
Filter-Modus — - ist stdin / stdout
Jede kompilierte Binary funktioniert auch als Unix-Filter:
# PNG von stdin lesen, JPEG nach stdout schreiben
cat foto.png | ./enhance --INPUT=- --OUTPUT=- \
--stdout-format=jpg --silent > raus.jpg
# Zwei Filter verketten
cat in.jpg | ./grayscale --INPUT=- --OUTPUT=- --silent \
| ./watermark --INPUT=- --OUTPUT=- --silent \
--BRAND="© Acme" > final.png
Feature-Check
Was in jeder kompilierten Binary „einfach läuft", ohne externe Abhängigkeiten:
- PNG / JPEG / WebP / AVIF / TIFF lesen + schreiben
- Animiertes WebP + APNG + Multi-Page TIFF für Animationen
- EXIF beim Laden gelesen, beim JPEG-Save geschrieben (
meta.exif.*) - SVG-Import (resvg) und SVG-Export (vtracer) — voller Vektor-Loop
- 35+ Pixel-Operationen — Weichzeichnen, Schärfen, Warp, Blend, Farbkorrektur, Kantenerkennung, …
- Textrendering mit zwei eingebetteten Variable-Fonts (Inter, JetBrains Mono)
- WarpGrid-Mesh-Transformationen für Perspektive / 3D-Flächen-Projektion
- Eigene Convolution-Kernel für Schärfen / Prägen / Motion-Blur / etc.
Cross-Plattform-Builds
Der „Make Exe"-Button im Playground baut standardmäßig für Ihr aktuelles
OS. Cross-Compilation (z.B. Windows-.exe von macOS aus) ist ein
Pro-Feature — siehe Preisliste.
Auf der Kommandozeile:
# Nativ (Host-Plattform)
mlcos-compile-rs enhance.js --overwrite
# Ausgabename / -pfad überschreiben
mlcos-compile-rs enhance.js --name colour-enhancer --output ~/bin/
# Cross-Target (Pro): auf einen vorgebauten Stub für das Ziel-OS zeigen
mlcos-compile-rs enhance.js --stub ./stubs/mlcos-run-rs-windows-x64.exe
Windows: Icon und Dateieigenschaften
Eine kompilierte .exe trägt das OpticScript-Icon und füllt
Eigenschaften → Details: Produktname und Beschreibung kommen aus
//!TITLE: und //!DESC: des Skripts, die Version ist ohne Angabe
1.0.0. Eigene Angaben:
mlcos-compile-rs verbessern.js --icon logo.png --app-version 1.2.0 \
--company "Beispiel GmbH" --copyright "© 2026 Beispiel GmbH"
--icon nimmt eine .ico oder ein beliebiges PNG/JPEG/WebP — die
Größen, die Windows braucht, werden erzeugt. Das klappt auch, wenn unter
Linux oder macOS für Windows kompiliert wird (--stub …/mlcos-run-rs.exe).
macOS: lokal ja, weitergeben nein
Auf macOS laufen die erzeugten Binaries auf Ihrem Rechner einwandfrei — weitergeben lassen sie sich aber nicht.
Der Compiler haengt das Skript hinter das Dateiende des Stubs. Fuer den
Kernel ist das unsichtbar, er prueft nur bis zum codeLimit der
Signatur. codesign sieht es sehr wohl:
codesign --verify ./enhance → main executable failed strict validation
spctl --assess ./enhance → rejected
codesign --sign - ./enhance → verweigert die Signatur ganz
Die Datei laesst sich also weder signieren noch notarisieren. Solange sie auf Ihrem Rechner bleibt, merkt niemand etwas davon: lokal erzeugte Dateien tragen kein Quarantine-Attribut, und Gatekeeper sieht sie nie an. Sobald jemand sie herunterlaedt oder per AirDrop bekommt, lehnt Gatekeeper sie ab — und zwar ohne Umweg fuer den Empfaenger.
Fuer die Weitergabe an macOS-Nutzer nehmen Sie deshalb einen der
leichteren Wege aus dem naechsten Abschnitt (Wrapper-Skript oder das
blanke .js), oder Sie liefern das Skript und lassen den Empfaenger
mlcos-compile-rs selbst aufrufen. Windows und Linux sind davon nicht
betroffen.
Drei Wege zur Distribution, sortiert nach Aufwand
Nicht jedes Mal braucht es einen vollständigen Compile. Wenn Ihr Publikum den OpticScript-Installer schon hat, gibt es leichtere Varianten:
| Zielgruppe | Was Sie ausliefern | Was sie installieren |
|---|---|---|
| Eigenes Team / intern | enhance.js + mlcos-run-rs enhance.js … |
OpticScript |
| Poliertes Tool, intern | mlcos-compile-rs --wrap=auto enhance.js → enhance.cmd / enhance.sh |
OpticScript |
| Externe Nutzer | enhance.exe (kompiliert) |
Nichts |
Kompilierte Binaries sind die Antwort für die dritte Zeile — die, in der Sie null Rückfragen vom Empfänger wollen.
Fehlerbehebung
INPUT is not definedzur Laufzeit — das Skript verwendetINPUT, deklariert aber//!INPUT: INPUTnicht (oder den passenden Key). Die Direktive ergänzen, damit der Compiler weiß, was er verdrahten soll.batch mode … requires a placeholder— Ihr Eingabe-Flag passte auf mehrere Dateien, aber der Ausgabe-Pfad ist fix. Einen Platzhalter wie{stem}in die Ausgabe einbauen.two inputs are multi-valued patterns; only one input may batch— Eine der Eingaben auf eine einzelne Datei fixieren; die andere darf weiter batchen.
Siehe auch
- Erste Schritte — JS-Engine-Tour.
- API-Referenz — jede
Engine.*-Methode. - Beispiele — 70+ funktionierende Skripte. Im Playground öffnen, kompilieren, versenden.