AutoHotkey - Schnelles UI-Prototyping mit minimalen Executables

AutoHotkey ist eine kostenlose, quelloffene Skriptsprache für Windows, die ursprünglich zur Tastatur- und Mausautomatisierung entwickelt wurde. Sie eignet sich hervorragend für die schnelle Erstellung von grafischen Benutzeroberflächen und kompakten ausführbaren Dateien.

Die einzigen Voraussetzungen sind ein Windows-Betriebssystem ab Version 7 sowie die Installation der AutoHotkey-Laufzeitumgebung. Es werden keine zusätzlichen Frameworks, Laufzeitbibliotheken oder Entwicklungsumgebungen benötigt. Die Installation umfasst lediglich wenige Megabyte.

Funktionalität

AutoHotkey arbeitet mit einfachen Textskripten, die von der AutoHotkey.exe interpretiert werden. Ein Skript kann Hotkeys, Hotstrings oder eine vollständige Benutzeroberfläche definieren. Für die GUI-Erstellung stellt AutoHotkey den Gui-Befehl bereit, mit dem man Fenster und Steuerelemente wie Textfelder, Buttons oder Checkboxen erzeugt. Dazu wird ein Gui-Objekt instanziiert, dem man schrittweise Steuerelemente hinzufügt und anschließend mit Show() anzeigt.

Man sollte auf jeden Fall AutoHotkey v2 verwenden. Die Version 1 wird nicht mehr weiterentwickelt und v2 bietet eine konsistentere Syntax, bessere Sicherheit und moderne Sprachfeatures. Die Syntax von v2 weist einige Besonderheiten auf. Zuweisungen erfolgen mit :=, Vergleiche mit = oder ==. Variablennamen sind case-insensitive, Funktionsnamen ebenfalls. Es gibt keine legacy Kommando-Syntax mehr wie in v1, stattdessen verwendet man durchgängig Funktionen und Objekte. Dadurch ist der Code leichter zu lesen, aber viele ältere Skripte aus v1 müssen angepasst werden.

Der eigentliche Vorteil liegt in der Geschwindigkeit: Mit wenigen Zeilen Code entsteht eine funktionale Oberfläche, die direkt getestet werden kann. Für die Verteilung kompiliert man das Skript mit dem mitgelieferten Ahk2Exe-Tool zu einer eigenständigen .exe-Datei. Diese enthält den Interpreter und das Skript in einer einzigen Binärdatei.

Pro und Kontra

Pro

  • Schnelles Prototyping von UIs, oft in unter einer Minute
  • Super schnelle Startuptime
  • Kompilierte Executables sind außergewöhnlich klein. Eine minimale .exe liegt bei etwa 800 KB, mit NTFS-Kompression sogar bei rund 350 KB
  • Keine Abhängigkeiten, die EXE läuft auf jedem Windows-System
  • Bei Bedarf lassen sich andere Programme oder Skripte per Run-Befehl aus dem AHK-Skript heraus starte

Kontra

  • AutoHotkey ist auf Windows beschränkt; es existiert keine Linux- oder macOS-Version
  • Der Sprachumfang ist begrenzt. Für komplexe Datenverarbeitung, Netzwerkprotokolle oder rechenintensive Aufgaben stößt man schnell an Grenzen
  • Sicherheitssoftware und einige Spiele erkennen AutoHotkey-Skripte als potenziell unerwünscht
  • AutoHotkey arbeitet single-threaded, was bei parallelen Aufgaben zu Verzögerungen führen kann

Das folgende Skript erstellt ein kleines Eingabefenster mit einem Textfeld und einem Button. Beim Klick auf den Button wird der eingegebene Text in einer MessageBox angezeigt.

#Requires AutoHotkey v2.0

; GUI-Objekt mit Titel erstellen
meineGui := Gui(, "Schnelle Eingabe")

; Textlabel hinzufügen
meineGui.AddText(, "Bitte einen Wert eingeben:")

; Eingabefeld mit Variablennamen ed1 hinzufügen
meineGui.AddEdit("w230 vWert")

; Button hinzufügen und Klick-Event verknüpfen
meineGui.AddButton("Default w80", "OK").OnEvent("Click", zeigeWert)

; Fenster anzeigen
meineGui.Show()

; Funktion, die beim Klick ausgeführt wird
zeigeWert(*) {
    gespeichert := meineGui.Submit()
    MsgBox(gespeichert.Wert, "Eingabe", "Iconi")
}

Für schnelle interne Tools, Prototypen und kleine Automatisierungsaufgaben unter Windows ist AutoHotkey eine hervorragende Wahl. Die Kombination aus minimaler Executable-Größe und der Möglichkeit, bei Bedarf externe Programme aufzurufen, macht es besonders für Szenarien interessant, in denen man eine leichtgewichtige UI benötigt, ohne eine vollständige Entwicklungsumgebung aufzusetzen. Für plattformübergreifende Anwendungen oder Projekte mit komplexer Datenverarbeitung sollte man hingegen auf andere Werkzeuge zurückgreifen.

Die offizielle Dokumentation mit ausführlichen Beispielen und Referenzen findet man unter autohotkey.com. Das GitHub-Repository mit dem Quellcode und dem Compiler Ahk2Exe ist unter github.com/AutoHotkey/AutoHotkey erreichbar.

MiniSearch - Volltextsuche mit minimalem Overhead

MiniSearch ist eine JavaScript-Bibliothek, die client- und serverseitige Volltextsuche ermöglicht, indem sie einen invertierten Index im Arbeitsspeicher des Browsers oder Node.js-Servers aufbaut. Der Index wird vollständig im Arbeitsspeicher gehalten, wodurch die Datenmenge, die durchsucht werden kann, begrenzt ist. Auch wird der Index beim Starten immer neu aufgebaut, was für größere Mengen an Daten nicht ideal ist. Bei Versuchen mit ca. 6 MB an Daten hat der Aufbau des Index nur ca. 860 ms gedauert. Eine Fuzzy-Suche war meist in unter einer ms durchgeführt.

MiniSearch ist eine reine JavaScript-Bibliothek ohne externe Abhängigkeiten. Dadurch ist sie auch ideal, wenn ein kleines serverseitiges Projekt mit einer Volltextsuche ausgestattet werden muss, wo Solr oder auch schon Meilisearch viel Overhead benötigen. MiniSearch hingegen kann direkt eingebunden und verwendet werden. Auch die Nutzung im Browser in einer PWA ist ideal.

Die Kernfunktionalität von MiniSearch basiert auf einem Radix Tree (einem platzoptimierten Präfixbaum) für den invertierten Index. Dieser Ansatz macht die Indexierung und Suche nicht nur schnell, sondern auch besonders speichereffizient, was für mobile Browser entscheidend ist.

Es ist möglich, Dokumente zur Laufzeit hinzuzufügen und zu entfernen. Die Bibliothek bietet erweiterte Suchfunktionen wie Präfix-Suche, Fuzzy-Suche für Tippfehler und Field Boosting zur Gewichtung von Feldern, sodass Treffer in Titelfeldern höher bewertet werden können als z.B. in der Beschreibung. MiniSearch bietet viele Funktionen, die man bei einer so kleinen Suche nicht erwarten würde. So generiert Die Auto-Suggestion-Funktionalität Vorschläge direkt aus den indizierten Dokumenten und sortiert sie nach Relevanz.

Im Vergleich zu schwergewichtigen Lösungen wie Solr oder Meilisearch punktet MiniSearch durch minimalen Overhead. Während diese serverbasierten Lösungen erhebliche Ressourcen benötigen, kann MiniSearch direkt im Anwendungsprozess operieren.

FrankenPHP und RoadRunner: Moderne App-Server für PHP

FrankenPHP und RoadRunner ersetzen den traditionellen PHP-FPM-Ansatz. Sie führen PHP-Anwendungen als dauerhafte Prozesse aus, die im Speicher bleiben, anstatt sie bei jeder Anfrage neu zu starten. Dieser Architekturwechsel bringt erhebliche Performance-Vorteile, insbesondere für framework-basierte Anwendungen mit hohem Initialisierungsaufwand. Beide Projekte sind Open-Source und können kostenlos genutzt werden.

FrankenPHP

FrankenPHP ist ein in Go geschriebener Application Server, der die PHP-Laufzeitumgebung direkt in den modernen Caddy-Webserver einbettet . Diese enge Integration erlaubt eine einfache Handhabung.

Man sollte beachten, dass FrankenPHP in zwei Modi betrieben werden kann:

  • Klassisch: Funktioniert als Drop-in-Ersatz für PHP-FPM und bietet sofortige Performance-Verbesserungen ohne Codeänderungen .
  • Worker-Modus: Hier bootet die gesamte Anwendung einmal und verbleibt im Speicher. Dies kann die Antwortzeiten laut Benchmarks um das 3,5-fache im Vergleich zu FPM verbessern, da der Framework-Initialisierungsaufwand für jede Anfrage entfällt.

Weitere herausragende Merkmale sind die native Unterstützung für moderne Protokolle wie HTTP/2 und HTTP/3, die automatische Verwaltung von HTTPS-Zertifikaten und die Möglichkeit, Anwendungen als eigenständige, portierbare Binärdateien zu bauen.

RoadRunner: Der leistungsstarke Manager

RoadRunner, ebenfalls in Go implementiert, verfolgt einen anderen Ansatz. Es handelt sich um einen High-Performance Application Server, der persistente PHP-Worker-Prozesse verwaltet . Anstatt PHP selbst einzubetten, startet und überwacht RoadRunner separate PHP-Worker und leitet Anfragen über eine schnelle Brücke an sie weiter.

Seine Stärken liegen in der hervorragenden Integration mit großen Frameworks wie Laravel oder Symfony und einem reichhaltigen Plugin-System, das Aufgaben wie Queue-Verarbeitung, gRPC und das Servieren statischer Dateien abdeckt . Dies macht es besonders geeignet für skalierbare Dienste, APIs und Anwendungen mit hohem Durchsatz.

Die Konfiguration und das Debugging gelten als anspruchsvoller als bei FrankenPHP.

Notwendige Anpassungen

Die Entscheidung für einen persistenten Application Server erfordert Anpassungen an der Architektur. Der größte Unterschied ist der Verlust der Prozessisolation. Während bei FPM jeder Request in einer sauberen Umgebung startet, kann globaler Zustand von einer Anfrage zur nächsten in einem Worker bestehen bleiben. Anwendungen müssen daher sorgfältiger mit globalen Variablen und der Initialisierung von Zuständen umgehen .

Zudem benötigt der Worker-Modus von FrankenPHP eine thread-sichere PHP-Version (ZTS), was die Kompatibilität mit einigen PHP-Erweiterungen einschränken kann. Für maximale Performance sollte der Bootstrap-Code der Anwendung so optimiert werden, dass er problemlos mehrmals in einem persistenten Worker ausgeführt werden kann.

Fazit

Mit FrankenPHP und RoadRunner stehen zwei ausgereifte und leistungsstarke Alternativen zu PHP-FPM zur Verfügung. Beide lösen das Problem des Kaltstarts von PHP-Anwendungen auf elegante Weise und ermöglichen so einen modernen, wettbewerbsfähigen Betrieb.

  • FrankenPHP überzeugt durch seine einfache Integration, den mitgelieferten Caddy-Server und seine raw Performance in Benchmarks.
  • RoadRunner punktet mit seiner Reife, einer breiten Funktionspalette durch Plugins und einer stabilen Architektur für komplexe, skalierbare Dienste.

Die Wahl zwischen ihnen hängt letztlich von den spezifischen Anforderungen des Projekts, der bestehenden Infrastruktur und den Vorlieben des Entwicklungsteams ab.

Abschließend ist es erwähnenswert, dass große Plattformen wie Facebook auf eigene, hochspezialisierte Lösungen wie HHVM und HackHack setzen, während FrankenPHP und RoadRunner diese moderne Architektur als praxistaugliche Werkzeuge für die gesamte PHP-Community bereitstellen.

NPM Packages - Patchen

Das Patchen von NPM-Paketen bezeichnet das gezielte Verändern des Quellcodes einer externen Bibliothek in einem Node.js-Projekt. Dies wird typischerweise dann notwendig, wenn ein kritischer Bug die eigene Anwendung betrifft, aber das offizielle Update des Paket-Maintainers noch nicht verfügbar ist. Diese Methode eignet sich auch für kleine, projekt-spezifische Anpassungen an einem Paket. Eine Alternative wäre das Erstellen eines Forks des Pakets, was jedoch mit einem erheblich größeren Aufwand verbunden ist.

Vorgehensweise mit patch-package

Ein beliebtes Werkzeug für diesen Prozess ist das NPM-Paket patch-package. Die Vorgehensweise ist wie folgt:

  1. Installieren npm i patch-package
  2. Erweitern der package.json um einen Postinstall-Step:
...
"scripts": {
     "postinstall": "patch-package"
}
...
  1. Manuell anpassen des Codes des zu patchenden Pakets innerhalb des node_modules-Ordners.
  2. npx patch-package <paket-name> aufrufen. Dadurch wird ein Diff erstellt und automatisch eine Patch-Datei abgelegt. Der Patch enthält die Unterschiede zwischen dem originalen und dem geänderten Code.
  3. Testen: npm i sollte nach der Installation automatisch das Paket patchen. Nachfolgend eine Beispielausgabe des Patchvorgangs:
patch-package
patch-package 8.0.1
Applying patches...
react-slick@0.30.3 ✔

Man sollte Patches immer nur als vorübergehende Lösung betrachten, bis ein offizielles Update des Originalpakets verfügbar ist. Den gefundenen Bug und den erstellten Fix sollte man idealerweise dem Maintainer des Originalpakets melden, beispielsweise via Pull Request auf GitHub. Zudem sollte man beachten, dass Patches bei größeren Updates des Originalpakets Konflikte verursachen können, die dann nach jedem update aufgelöst werden müssen.

Wicked Engine - OpenSource C++/Lua-Game-Engine

Bei der Wicked Engine handelt es sich um eine cross-plattform 3D-Grafikengine unter der MIT-Lizenz Ihr erklärtes Ziel ist es, einen modernen Renderer bereitzustellen, der die neuesten Grafikkarten-APIs voll ausreizt. Sie soll einfach zu bedienen sein und den Nutzer nicht mit komplexen Abhängigkeiten belasten.

Kernfeatures:

  • Leistungsstarkes Rendering:
    Moderne Tiled-Forward-Renderer mit einem cleveren Visibility-Buffer-System für Effekte wie Temporal AA und SSR, die sonst nur deferred möglich wären .
  • Volle Nutzung von DirectX 12 und Vulkan inklusive Hardware-Raytracing, HDR und Variable Rate Shading (VRS) .
  • C++-Framework für maximale Leistung und Kontrolle.
  • Lua-Scripting zur Laufzeit, ideal für Rapid Prototyping und Gameplay-Logik.
  • Importiert Formate wie GLTF 2.0, FBX, OBJ und das native WISCENE.
  • Spezieller Support für VRM-Charactermodelle, perfekt für Anime-Projekte und V-Tuber .
  • Plattformübergreifend
    • Läuft auf Windows 10+ und Linux .
    • Experimentell auch für Xbox Series X|S und PlayStation 5
  • Terrain Unterstützung mit Editor
  • Mesh Blending
  • Wetter und Sky-System

Leider gibt es keinen VR-Support und dieser ist auch nicht geplant.

Die Wicked Engine kann über Steam installiert werden oder einfach über die Webseite wickedengine.net bezogen werden.

Umgang mit HEAD-Anfragen in Astro.js für UptimeRobot und Co.

Beim Einsatz von Monitoring-Diensten wie UptimeRobot, die HEAD-Anfragen nutzen, um die Verfügbarkeit einer Website zu prüfen, kann es in Astro im Produktionsmodus zu Problemen kommen. Diese Dienste senden oft keinen Origin-Header, was zu einer 403-Antwort führt. HEAD-Anfragen ohne Origin-Header werden von Astro.js im Produktionsmodus abgelehnt, was Monitoring-Dienste wie UptimeRobot dazu veranlasst die Website als down anzusehen. Um das zu beheben kann in der Astro-Konfiguration die Sicherheitsprüfung für den Origin-Header deaktiviert werden.

astro.config.mjs

export default defineConfig({
    security: {
        checkOrigin: false, // for head requests -> uptimerobot
    },
});

Durch das Setzen von checkOrigin: false in der Astro-Konfiguration wird sichergestellt, dass Dienste wie UptimeRobot HEAD-Anfragen erfolgreich durchführen können, ohne eine 403-Antwort zu erhalten.

Hinweis: Diese Einstellung sollte mit Vorsicht verwendet werden, da sie Sicherheitsprüfungen beeinflusst.

Self-Host Google-Fonts

Aus Datenschutzgründen kann es problematisch sein, Fonts von Google-Servern einzubinden. Google-Fonts erlaubt es, alle benötigten Font-Dateien als ZIP herunterzuladen. Allerdings generiert es nicht die dafür notwendigen CSS-Dateien. Natürlich ist es möglich, diese manuell zu erstellen, einfacher geht es aber mit dem Dienst: gwfh.mranftl.com. Hier kann man ebenfalls alle Google-Fonts heruntergeladen, allerdings kann man sich hier mit wenigen Klicks ein passendes CSS generieren lassen.

Die Benamung der Dateien unterscheidet sich von der der bei Google, deswegen ist es einfacher die von mranftl bereitgestellte ZIP-Datei zu verwenden.

Vor der Nutzung von heruntergeladenen Fonts gilt es selbstverständlich, zu überprüfen, ob die Lizenz die gewünschte Nutzung ermöglicht.

Gluon.js & Neutralino - Zwei Newcomer vordern Electron und NW.js heraus

Zwei Newcomer vorderen Electron und NW.js bei Erstellen von JavaScript-Desktopaplikationen heraus. Die beiden neuen Tools erzeugen weit kleinere Applikationen als die eingesessenen Konkurrenten. Anwendungen sind nur wenige MB und nicht mehrere Hundert MB groß. So liefern beide keine Chrome-Runtime mit. Dadurch lässt sich schon ca. 60 MB sparen. Gluon setzt einen bereits installierten Chrome oder Firefox voraus. Neutralino setzt auf die in dem jeweiligen Betriebssystem integrierte Browser-Technologien (z.B. gtk-webkit2 unter Linux). Es kann immer noch clientseitiges JavaScript ausgeführt werden, außerdem bieten beide die Möglichkeit ein Backend anzubinden. Diese Funktionalität ist für viele Anwendungsfälle ausreichend, oft wird wahrscheinlich überhaupt keine Backendfunktionalität benötigt, auch wenn solche Anwendungen dann auch als PWA umgesetzt werden könnten, bevorzugen es manche dennoch diese als Desktop-Anwendung zu vertreiben.

Neutralino

Neutralino verzichten auf eine Node.js Runtime. Es kann noch immer auf die integrierten APIs zugegriffen werden. Im Gegensatz zu Gluon stehen über die Neutralion API viele Desktop-Funktionen zur Verfügung. Deswegen kann oft auf ein Backend verzichtet werden. Dennoch kann über IPC/Websockets ein solches angebunden werden. Das Backend kann in beliebiger Technologie umgesetzt werden, solange diese Websockets unterstützt. Es existieren Beispiele für C++ und Node.js. Anwendungen können über das integrierte neu build Befehl für Windows, Linux und MacOS erstellt werden. Teilweise wird auch bereits ARM64 unterstützt.

Gluon

Gluon ist ein noch sehr neues Projekt. Dennoch hat es bereist sehr viel Aufmerksamkeit erzeugt. Als Backend könne Node, Deno oder Bun verwendet werden. Dabei wird die Anbindung an den Client wie bei Neutralino auch über IPC umgesetzt. Leider verfügt Gluon noch über kein integriertes "build"-Kommando. Beide Tools befinden sich momentan noch in einer frühen Entwicklungsphase und sind deswegen nicht für große Anwendungen geeignet. Auch haben sie das Problem, dass der Entwickler nicht weis, in welcher Umgebung seine Anwendung ausgeführt wird. Wer damit leben kann, sollte den beiden Tool auf jeden Fall einmal anschauen.

zx - Ein Werkzeug für einfachere Konsolen-Scripte in Node.js

Bash-Scripte sind schnell geschrieben, allerdings erschwert die gewöhnungsbedürftige Syntax es, komplexere Skripte zu schreiben. JavaScript ist eigentlich eine perfekte, um Scripte zu schreiben (was das Script im Namen ja bereits andeutet), aber die Verwendung der Node.js-Standardbibliothek ist leider nicht intuitiv. Das zx-Paket, das als Open-Source von Google bereitgestellt wird, stellt nützliche Wrapper für child_process bereit und liefert darüber hinaus einiges an sinvollen Funktionen.

zx kann über npm i -g zx global installiert werden, einzige Vorausetztung ist ein installiertes Node/NPM.

Hier ein einfaches Beispiel-Script:

#!/usr/bin/env zx
await $`cat package.json | grep name`

let branch = await $`git branch --show-current`
await $`dep deploy --branch=${branch}`

await Promise.all([
    $`sleep 1; echo 1`,
    $`sleep 2; echo 2`,
    $`sleep 3; echo 3`,
])

let name = 'foo bar'
await $`mkdir /tmp/${name}`

Es werden folgende Befehle bereitgestellt:
  • $ - Führt angegbenen Befehl über spawn aus
  • cd()
  • fetch()
  • question()
  • sleep() 
  • echo()
  • stdin()
  • within()
  • retry()
  • spinner()- Rendert einen Spinner/Ladeanimation auf der Konsole
  • chalk - Ermöglicht farbige Ausgaben auf der Konsole
  • fs 
  • os 
  • path 
  • glob
  • yaml - Ermöglicht das einlesen von YAML
  • minimist - Einfaches parsen von Argumenten
  • which 
  • filename 
  • dirname 
  • require()

Mehr zu zx unter github.com/google/zx

NPM-Pakete komfortabler aktuell halten

Mit den beiden Paketen npm-check und npm-check-updates gibt es zwei Tools, die es Entwicklern erleichtern Node.js und Java-/Type-Script Projekte aktuell zu halten. Beide Tools analysieren die package.json bzw. die package-log.json und listen mögliche Updates auf. Im interaktiven Modus können updates Pakete direkt ausgewählt und installiert werden. Es empfiehlt sich Tools über npx auszuführen und nicht lokal/global zu installieren. Dadurch ist gewährleistet, dass immer die aktuellste Version verwendet wird.

npm-check im Interaktiven Modus:

npx npm-check -u 

npm-check-updates im Interaktiven Modus:

npx npm-check-updates --format group --interactive

npm-check bietet im interaktiven Modus (-u) eine detailliertere Darstellung der Pakete gefällt deswegen besser als npm-check-updates.