Est. 2007 Intermediate

QtScript

QtScript (Qt Script) is the ECMAScript-based application-scripting language and engine that Trolltech shipped inside Qt 4.3 in May 2007 to replace Qt Script for Applications (QSA): JavaScript with Qt signal-and-slot connections and automatic QObject bindings, re-based on WebKit's JavaScriptCore in Qt 4.6, used to run the first QML, deprecated in Qt 5.5 and dropped from Qt 6.0

Created by Trolltech ASA of Oslo, Norway (from 2008 Qt Software at Nokia, from 2012 Digia and from 2014 The Qt Company). Kent Hansen was the Trolltech/Nokia engineer who announced QtScript on the Qt Labs blog on 5 January 2007, maintained the Qt Script Generator bindings from 2008 to 2012 and blogged the JavaScriptCore and V8 back-end work of 2009-2011; QtScript's immediate predecessor QSA (2003) was Trolltech's, and the JavaScriptCore engine underneath QtScript from Qt 4.6 descends from KDE's KJS via Apple's WebKit

Paradigm Procedural and prototype-based object-oriented scripting in the ECMAScript (ECMA-262, 3rd edition) tradition, extended with event-driven programming through Qt signals and slots (Function.prototype.connect) and with automatic reflection of QObject-derived C++ classes - properties, signals, slots and child objects - into script objects
Typing Dynamic and weak, as in ECMAScript 3: undefined, null, boolean, number, string and object, plus QtScript's QObject, QVariant and QMetaObject wrapper objects; values cross to C++ through QScriptValue and QVariant conversions, with qScriptRegisterMetaType() for custom types
First Appeared 2007 - announced on the Qt Labs blog on 5 January 2007 and shipped in Qt 4.3.0 on 30 May 2007 as the QtScript module (QT += script) of the Qt Desktop and Open Source editions. Its predecessor, Trolltech's Qt Script for Applications (QSA) 1.0, dates from 2 July 2003
Latest Version Qt Script 5.15.x, unchanged in substance since the Qt 5.15.2 open-source release of 13 November 2020; the last tags in the qt/qtscript repository are v5.15.19-lts (19 May 2025, commercial), v5.15.18-lts-lgpl (31 October 2025) and v5.15.19-vxworks-lts (18 December 2025). The last code change on the 5.15 branch is dated 26 October 2021. Qt 6.0 (8 December 2020) shipped without the module; QJSEngine in the Qt QML module is the designated replacement

QtScript - “Qt Script” in the documentation, the QtScript module and QScript* classes in code - is the JavaScript that lived inside the Qt application framework from 2007 to 2020. It is ECMAScript 3 with Qt bolted on: a C++ program creates a QScriptEngine, hands it its QObjects, and the objects’ properties, signals, slots and children appear in script, where a signal can be wired to a function with button.clicked.connect(f). Trolltech built it to replace a separately sold product, Qt Script for Applications, then rebuilt it on WebKit’s JavaScriptCore, used it to run the first QML, tried to move it to V8, and finally let it go when Qt 6 arrived. Along the way it was the scripting language of Amarok, Plasma, Stellarium, MuseScore and Qt’s own build tool.

History and Origins

Qt Script for Applications (2003-2008)

Trolltech’s first scripting product was announced from Oslo on 2 July 2003. Qt Script for Applications (QSA) 1.0 “takes static Qt/C++ applications, and makes them dynamic”, the press release said; Trolltech’s president Eirik Eng promised that “all developers need to do is add a few lines of code to their Qt applications, and then the apps are enabled for scripting and extending.” QSA was a separate library, dual-licensed under the GPL and a commercial licence, and it was more than an interpreter: it came with QSA Workbench, an editor with completion and project management, and C++ classes (QSInterpreter, QSProject, QSEditor) for embedding them.

The language QSA interpreted was already called “Qt Script”, and it was an odd hybrid. Qt’s later porting guide describes it as “derived from ECMAScript 3.0 and 4.0”: the built-in library followed the third edition of ECMA-262, but “most of the run-time logic, such as classes and scoping rules, is based on the ECMAScript 4.0 proposal”, so QSA programmers wrote class Car { var regNumber; function Car(n) { ... } } with static members and C++-style inheritance. The ECMAScript 4 proposal was eventually abandoned, which left QSA speaking a dialect no other engine spoke. The last version, QSA 1.2.2, has documentation copyrighted 2006; Trolltech’s notice that “QSA for Qt 4 will reach end of life status December 1st, 2008” and that “a new scripting engine will be available with Qt 4.3 conforming to ECMA Standard 262” was quoted by projects that had built on it.

QtScript in Qt 4.3 (2007)

The new engine was previewed by Kent Hansen on the Qt Labs blog on 5 January 2007 under the title “Say hello to QtScript!” and shipped in Qt 4.3.0 on 30 May 2007. KDE.news summarised the release’s headline features as “QtScript, an ECMAscript standard application scripting engine, replacing QSA; SSL support; improved OpenGL engine”. Unlike QSA it was part of Qt itself - “the QtScript module is part of the Qt Desktop Edition and the Qt Open Source Edition”, linked with QT += script - and unlike QSA it was, in the porting guide’s words, “only an interpreter, it does not provide an editor, completion or script project management”, but it “provides almost full compliance with the ECMAScript standard and performs significantly better”. The 4.3 module had six public classes: QScriptEngine, QScriptValue, QScriptValueIterator, QScriptContext, QScriptable and QScriptExtensionPlugin.

Qt 4.4 (May 2008) filled in the API - qScriptConnect() for connecting a signal to a script function from C++, abortEvaluation(), automatic handling of QObject-derived slot arguments - and Qt 4.5 (March 2009), the release that also took Qt to the LGPL, added a second module, QtScriptTools, whose QScriptEngineDebugger gave applications a drop-in graphical debugger, along with checkSyntax(), setGlobalObject() and multi-line string literals.

The generator and “scripting in the large” (2008-2009)

Two projects widened QtScript’s ambitions. The Qt Script Generator, imported from Trolltech’s Labs Subversion into git on 3 July 2008 and maintained by Kent Hansen into 2012, parsed Qt’s own headers and produced binding plugins for the whole Qt API, so that a script could qs.script.importExtension("qt.gui") and build a complete GUI without any C++. Amarok 2 shipped those bindings with its scripts; MuseScore did the same and later counted the cost - more than 1,100 generated files and 297,000 lines.

The second was the change of engine. During 2009 Nokia’s Qt developers replaced the interpreter written for 4.3 with JavaScriptCore, the engine of Apple’s WebKit, which itself descends from KJS, the JavaScript engine KDE wrote for Konqueror. Qt 4.6 (1 December 2009) recorded the switch tersely: “The QtScript module is now based on the 3rdparty JavaScriptCore library. It is only available under the LGPL or a compatible license.” The changelog promised “many optimizations” and “improved ECMA script compliance”, and warned of two behaviour changes: Date no longer went through QDateTime, and RegExp objects were “no longer thin wrappers around QRegExp; they are now ‘proper’ JavaScript RegExp objects.” Hansen’s Qt Labs post of 23 November 2009, “QtScript in 4.6”, put numbers on it with SunSpider run under Qt 4.5 and 4.6 on his Linux machine (the charts show speed-ups relative to 4.5 per SunSpider test; no absolute times were published), and read them as a change of scope: pre-4.6 QtScript was “sufficient for ‘scripting in the small/medium’, but with 4.6 it gains the ability to better tackle ‘scripting in the large’”. He also cautioned that “it’s not always going to be faster”: JavaScriptCore always JIT-compiled (there was no hot-spot detection), so for a tiny script such as 1 + 2 compiling could cost more than the old stack-based VM’s interpretation - the reason QScriptProgram, which caches the compiled form, was slipped into 4.6 as an internal class and made public in 4.7. The SunSpider suite remains in the module’s benchmarks and third-party attribution pages.

QML, V8 and the split (2010-2012)

Qt 4.7 (21 September 2010) added QML and Qt Quick, “a declarative language oriented on JavaScript”, and the QtDeclarative engine that ran QML bindings was built directly on QScriptEngine - the private engine header includes QtScript/qscriptengine.h, QScriptClass and QScriptString. QtScript thereby became the runtime of Nokia’s mobile user-interface strategy. The same release “significantly improved performance of the Qt/C++<–>JavaScript bridge” and made QScriptProgram, for pre-compiling scripts, a public class.

That success exposed the module’s weakness. On 20 January 2011 Hansen wrote that “we want Qt to have the best possible JavaScript technology. To make this happen, we need the ability to make drastic changes to the implementation - even replacing it - underneath our public APIs. If an API exposes implementation details, that will cause us to limp.” A month later, on 24 February, “Qt people, our JavaScript platform is burning rubber” announced open work on a V8 back-end: “the status of the V8-based back-end is that we still have some QtScript API that’s not implemented, and there are autotests failing, but several of the QtScript and QML examples and demos run.” The wip/v8 branch of the module was worked on until July 2011. The outcome was not a V8-backed QtScript but a fork in the road: QML got V8 (and, from Qt 5.2, Qt’s own V4 engine) through a new, smaller class, QJSEngine, while QtScript kept JavaScriptCore. On 27 April 2011 the module was cut out of the monolithic tree (“Initial import from the monolithic Qt”) as the qtscript repository, and Qt 5.0 (19 December 2012) shipped it as a compatibility module still sitting on a JavaScriptCore snapshot dated 27 January 2011 - the snapshot it carries to this day.

Deprecation and removal (2015-2020)

Qt 5.5 (July 2015) made the position official: “With Qt 5.5 the following modules are deprecated: Qt WebKit, Qt Declarative (Qt Quick 1), Qt Script. These modules are still included in the Qt 5.5 release, but considered for removal in the future releases of Qt.” The module page acquired the warning that has headed it since: “This module is not actively developed. It is provided for backwards compatibility with Qt 4 only. For new code, use QJSEngine and related classes in the Qt QML module instead.” Qt 5.15 LTS (26 May 2020) was the last feature release to carry it, and the Qt 6.0 release notes of 8 December 2020 list Qt Script and Qt Script Tools among the “Removed Modules in Qt 6.0”, with the boilerplate that “they may be re-introduced in a future release of Qt 6”. They have not been. The 5.15 branch lived on as commercial long-term support - v5.15.3-lts on 3 March 2021, with matching -lts-lgpl tags following about a year behind - but Qt Script’s commits in it are version bumps; the last substantive change, a sanitizer suppression in the JavaScriptCore heap code, is dated 26 October 2021, and the final tags are v5.15.19-lts (19 May 2025), v5.15.18-lts-lgpl (31 October 2025) and v5.15.19-vxworks-lts (18 December 2025).

Design Philosophy

Standard JavaScript, plus Qt

QSA’s lesson was that a private dialect is a liability. QtScript’s documentation therefore opens by placing it firmly in the standard: “Qt Script is based on the ECMAScript scripting language, as defined in standard ECMA-262. Microsoft’s JScript, and Netscape’s JavaScript are also based on the ECMAScript standard”, and it refers readers who do not know the language to JavaScript: The Definitive Guide rather than to a manual of its own. The “ECMAScript Compatibility” section claims the whole of ECMA-262’s built-in objects and then lists the extensions exhaustively, and the list is short: __proto__, __defineGetter__/__defineSetter__, Function.prototype.connect and disconnect, QObject.prototype.findChild, findChildren and toString, and a gc() function. Everything else Qt-specific arrives as objects the host application chooses to expose.

The QObject is the binding

The core idea, inherited from QSA and Qt’s meta-object system, is that a C++ class does not need a hand-written binding if it is a QObject. engine.newQObject(&button) wraps a widget; in script button.text, button.styleSheet and button.show() work because Qt’s meta-object already knows the properties and slots, and button.clicked.connect(function() { ... }) works because it knows the signals. The wrap options let the host decide how much to expose - whether child objects appear as properties, whether deleteLater() is reachable (Qt 4.5 added the option to hide it “so that scripts can’t delete application objects”), whether superclass members are included. QScriptable lets a C++ slot find out which engine and which this invoked it; QScriptClass lets C++ define objects with entirely custom property behaviour; QScriptEngineAgent lets a debugger or profiler watch execution. The design goal, stated in the Qt 4.3 module page, was simply “making Qt applications scriptable”.

Scripts as a product feature, not a language product

QtScript never had a standalone interpreter beyond the qscript example, no package ecosystem and no standard library beyond ECMAScript’s; qsTr() and QT_TR_NOOP() for translation were the only global functions Qt added, and even those needed installTranslatorFunctions(). It was designed as the scripting layer of something else, which is why its heaviest users were applications with plug-in cultures - a music player, a desktop shell, a planetarium, a notation editor - and why the loss of the module fell on them rather than on any community of “QtScript programmers”.

The Language

Hello, World

Because QtScript is ECMAScript, the plainest program is the plainest JavaScript. The qscript example shipped with the module is a small interactive shell that provides print():

1
print("Hello, World!");

The Qt-flavoured Hello World is the helloscript example, which is two files. The C++ side creates the engine and exposes a button:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
#include <QApplication>
#include <QPushButton>
#include <QtScript>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    QScriptEngine engine;
    engine.installTranslatorFunctions();

    QPushButton button;
    QScriptValue scriptButton = engine.newQObject(&button);
    engine.globalObject().setProperty("button", scriptButton);

    QFile scriptFile(":/helloscript.js");
    scriptFile.open(QIODevice::ReadOnly);
    engine.evaluate(QTextStream(&scriptFile).readAll(), "helloscript.js");
    return app.exec();
}

and the script, helloscript.js, drives the widget through its ordinary Qt properties and slots:

1
2
3
button.text = qsTr('Hello World!');
button.styleSheet = 'font-style: italic';
button.show();

Signals and slots

Qt’s callback mechanism appears in script as methods on the signal:

1
2
3
4
5
6
function onClick() {
    print("We got clicked!");
}
button.clicked.connect(onClick);
button.clicked.connect(function() { button.text = "Clicked"; });
button.clicked.disconnect(onClick);

A connection may name a receiver object as well as a function, so that this inside the slot is bound; if a signal is overloaded, Qt 4.5 onward requires the full signature (obj["valueChanged(int)"].connect(f)) rather than the bare name. Script functions can also be invoked as slots from C++ with qScriptConnect(), and a script can emit a signal simply by calling it. The QObject.prototype.findChild() extension mirrors QObject::findChild(), so a script given only a top-level window can navigate to the widgets it wants.

Objects, prototypes and the QSA migration

The porting guide’s worked example shows what changed between QSA’s classes and QtScript’s prototypes. QSA:

1
2
3
4
5
class Point {
    var x; var y;
    function Point(x, y) { this.x = x; this.y = y; }
    function manhattanLength() { return Math.abs(x) + Math.abs(y); }
}

QtScript, which has no class:

1
2
3
4
5
6
7
8
9
function Point(x, y) {
    this.x = x;
    this.y = y;
}
Point.prototype.manhattanLength = function() {
    return Math.abs(this.x) + Math.abs(this.y);
};
var p = new Point(3, -4);
print(p.manhattanLength());   // 7

The same prototype mechanism is how C++ extends script-side behaviour of value types: engine.setDefaultPrototype(qMetaTypeId<QPoint>(), proto) gives every QPoint returned from a slot a script prototype, and qScriptRegisterMetaType() supplies conversion functions for custom types.

The C++ API

ClassIntroducedPurpose
QScriptEngineQt 4.3Evaluate code, hold the global object, wrap QObjects and QMetaObjects, convert values
QScriptValueQt 4.3Container for any script value; toNumber(), toString(), property(), call(), construct()
QScriptContextQt 4.3A function invocation: thisObject(), argument(i), throwError()
QScriptableQt 4.3Lets a C++ slot access the calling engine and context
QScriptExtensionPluginQt 4.3Loadable extensions for importExtension() (the Script Generator’s output)
QScriptClass, QScriptClassPropertyIteratorQt 4.4Custom object classes with programmatic properties
QScriptEngineAgent, QScriptContextInfo, QScriptStringQt 4.4Execution tracing, backtraces, interned strings
QScriptEngineDebugger (QtScriptTools)Qt 4.5Graphical debugger with console, breakpoints, locals and stack views
QScriptSyntaxCheckResultQt 4.5Result of checkSyntax() for interactive shells
QScriptProgramQt 4.6 (internal), public in Qt 4.7Pre-parsed script for repeated evaluation

The rule of thumb in the documentation was “if you can express it as a QObject, you don’t need to write a binding” - and it is the part of the API that survived, in reduced form, as QJSEngine::newQObject() in Qt 5 and 6.

Evolution

Qt releaseDateQtScript
QSA 1.02 July 2003Separate add-on; ES3/ES4-hybrid “Qt Script”; QSA Workbench
Qt 4.330 May 2007QtScript module debuts with its own interpreter; QSA declared replaced
Qt 4.46 May 2008qScriptConnect(), abortEvaluation(), QScriptClass, QScriptEngineAgent
Qt 4.53 March 2009QtScriptTools debugger; checkSyntax(); LGPL licensing
Qt 4.61 December 2009Engine replaced by JavaScriptCore (LGPL-only); JIT; proper RegExp and Date
Qt 4.721 September 2010Runs QML/Qt Quick 1; QScriptProgram; faster C++ bridge
Qt 5.019 December 2012Separate qtscript repository; QJSEngine appears as the successor
Qt 5.5July 2015Deprecated
Qt 5.1526 May 2020Last feature release with the module
Qt 6.08 December 2020Removed

The module’s own source history since the 2011 split is compact: 33 commits by Kent Hansen and a long tail of build-system and licence-header maintenance by the Qt Project’s release engineers. The JavaScriptCore snapshot was refreshed in 4.7 and once more in January 2011 and then frozen, which is why Qt Script’s language level stopped where a January 2011 JavaScriptCore stopped: it never gained let, arrow functions, class or modules, the ECMAScript 2015 features that QJSEngine’s V4 engine later acquired.

Current Relevance

Running QtScript today

There is no Docker image and no standalone interpreter to download, but the module is still easy to build against on a 2025-era Linux system: Debian 12 “bookworm” (5.15.8), Ubuntu 24.04 (5.15.13) and Debian 13 “trixie” (5.15.15) all package qtscript5-dev, libqt5script5 and libqt5scripttools5. Building the qscript example from the module’s examples/script/qscript directory yields an interactive shell that evaluates typed-in ECMAScript and runs script files given on the command line, which is enough to run the language examples above. Applications that still depend on the module - anything built on Qt 5 that has not been ported - continue to work as long as Qt 5.15 does, and The Qt Company’s commercial 5.15 support, extended to five years, was scheduled to run to 26 May 2025 - although -lts tags kept appearing into December 2025 - and for open-source users the KDE project’s community patch collection is the only ongoing maintenance.

Migration

Most of QtScript’s larger users have moved. The Qt documentation’s advice is to use QJSEngine, whose evaluate(), newQObject(), globalObject() and QJSValue are near-copies of the QtScript originals; what is missing is QScriptClass, QScriptEngineAgent, the debugger and QScriptable. The projects that made the move recorded how uneven it was: Stellarium found the old module “more flexible and easier to fine-tune” and lists the lost isEvaluating() and pause() in its migration notes; Amarok warned that “previous scripts are often not compatible”; qbs chose QuickJS over QJSEngine altogether; MuseScore had already decided in 2012 that “the bindings are dead” and rebuilt on QML.

Why It Matters

QtScript was the mainstream way to script a C++ desktop application for the better part of a decade, and it did it with an idea that has outlived it: that a reflective object model - Qt’s meta-object system - can stand in for hand-written language bindings. A QObject handed to the engine was scriptable without another line of code, which is why a music player, a desktop shell and a planetarium could each grow a plug-in culture in the same language their users already knew from the web.

It is also a case study in what an embedded JavaScript engine costs its host. Trolltech wrote one interpreter, Nokia swapped it for JavaScriptCore, researched V8, and concluded that an API which exposed engine internals “will cause us to limp”; the successor, QJSEngine, exposes almost nothing of the engine underneath, and QML has since changed engines twice without breaking its users. QtScript’s deprecation notice - “provided for backwards compatibility with Qt 4 only” - is the epitaph of a module that was, for Qt 4.7 and 4.8, the runtime of QML itself.

Sources

  • Qt 4.3 documentation, QtScript Module (doc.qt.io/archives/4.3/qtscript.html); Qt 4.8 documentation, Making Applications Scriptable, ECMAScript Reference and Moving from QSA to Qt Script (doc.qt.io/archives/qt-4.8/)
  • Qt 5.15 documentation, Qt Script module page and third-party attribution (JavaScriptCore snapshot 2011-01-27, SunSpider benchmarks)
  • Qt 6.0 documentation, What’s New in Qt 6.0, “Removed Modules in Qt 6.0”
  • Qt wiki: New Features in Qt 5.5 (Deprecated Functionality), Qt version history, Qt History
  • dist/changes-4.3.0 through changes-4.7.0 in the qt/qt repository (GitHub mirror)
  • qt/qtscript repository (code.qt.io / GitHub): tags v5.0.0 to v5.15.19-vxworks-lts, branches 5.15 and wip/v8, examples/script/helloscript and examples/script/qscript
  • qt-labs/qtscriptgenerator repository (code.qt.io), initial import 3 July 2008
  • QSA 1.2.2 documentation archive (doc.qt.io/archives/qsa-1.2.2/); Trolltech press release “Trolltech Introduces Qt Script for Applications, (QSA) Version 1.0”, LWN.net, 2 July 2003
  • KDE.news, “Trolltech Releases Qt and Qtopia Core 4.3”, 4 June 2007
  • Kent Hansen, Qt Labs / Qt Blog: “QtScript Bindings for Animations & States Classes” (4 June 2009), “Resolving QtScript’s legacy APIs” (20 January 2011), “Qt people, our JavaScript platform is burning rubber” (24 February 2011), “Say Hello to Envjs for QtScript” (10 March 2011); “QtScript in 4.6” (23 November 2009, read from the Wayback Machine capture of labs.qt.nokia.com/2009/11/23/qtscript-in-46/ dated 19 January 2011); “Say hello to QtScript!” (5 January 2007) as cited by Wikipedia and search indexes
  • Lars Knoll, “Qt 5.15 LTS Released” (26 May 2020) and “Qt 6.0 Released” (8 December 2020), Qt Blog
  • Amarok ChangeLog (invent.kde.org/multimedia/amarok); Wikipedia, Amarok (software)
  • KDE TechBase, Development/Tutorials/Plasma4/JavaScript/API; Wikipedia, KDE Software Compilation 4
  • Stellarium ChangeLog, Scripting Engine (0.22 documentation) and StelScriptMgr Class Reference (1.x documentation)
  • MuseScore, “Introducing the new QML based plugin framework”, 10 July 2012 (SourceForge news mirror)
  • qbs repository changelog changes-2.0.0.md and tags
  • Daz 3D, Daz Studio 4 Reference Guide: Scripting
  • sources.debian.org and packages.ubuntu.com: qtscript-opensource-src 5.15.8 (Debian 12 bookworm), 5.15.15 (Debian 13 trixie) and 5.15.13+dfsg-1 (Ubuntu 24.04 noble)
  • Wikipedia, QtScript, Qt (software), WebKit

Timeline

2003
On 2 July 2003 Trolltech of Oslo announces Qt Script for Applications (QSA) 1.0, a separately sold add-on that makes Qt/C++ applications scriptable in 'Qt Script', an interpreted language based on the ECMAScript standard, with the QSA Workbench editor and project manager. QSA's dialect mixes ECMAScript 3 built-ins with class declarations taken from the (later abandoned) ECMAScript 4 proposal
2007
Kent Hansen's Qt Labs post 'Say hello to QtScript!' (5 January) previews a new in-house engine, and Qt 4.3.0 (30 May 2007) ships it as the QtScript module - QScriptEngine, QScriptValue, QScriptContext, QScriptable and friends - in both the commercial Desktop Edition and the GPL Open Source Edition. KDE.news describes it as 'an ECMAscript standard application scripting engine, replacing QSA'; a 'Moving from QSA to Qt Script' guide explains how to rewrite QSA classes as prototypes
2008
Qt 4.4 (6 May) adds qScriptConnect(), abortEvaluation() and an expanded module overview; the Qt Script Generator, which turns Qt's own headers into script bindings so that whole Qt applications can be written in QtScript, is imported from Trolltech's Labs Subversion into git on 3 July. Nokia completes its purchase of Trolltech the same year. Trolltech's notice that QSA for Qt 4 reaches end of life on 1 December 2008 is quoted by projects built on it. Amarok 2.0 (12 December) launches with a script system built on QtScript and the generator's Qt bindings
2009
Qt 4.5 (3 March), the first LGPL release of Qt, adds the QtScriptTools module with the QScriptEngineDebugger, plus checkSyntax(), setGlobalObject() and multi-line string literals. Stellarium 0.10.1 (2 February) makes QtScript its scripting engine; KDE 4.3 (4 August) ships the Plasma JavaScript engine. Qt 4.6 (1 December) replaces the original interpreter with WebKit's JavaScriptCore: 'The QtScript module is now based on the 3rdparty JavaScriptCore library. It is only available under the LGPL or a compatible license'
2010
Qt 4.7 (21 September) introduces QML and Qt Quick; the QtDeclarative engine that runs QML's JavaScript is built on QScriptEngine and the JavaScriptCore back-end, so the first generation of Qt Quick applications runs on QtScript. The release also makes QScriptProgram public (an internal class in 4.6), updates JavaScriptCore and reports 'significantly improved performance of the Qt/C++<-->JavaScript bridge'. KDE SC 4.4 (9 February) lets Plasma widgets be written in QtScript-powered 'Simplified JavaScript'
2011
Kent Hansen's posts 'Resolving QtScript's legacy APIs' (20 January) and 'Qt people, our JavaScript platform is burning rubber' (24 February) describe the plan to move Qt's JavaScript to Google's V8 and to obsolete the QtScript APIs that expose engine internals; a wip/v8 branch of the module is worked on until July. On 27 April 2011 QtScript is split out of the monolithic Qt tree into its own qtscript repository for the modular Qt 5
2012
Qt 5.0 (19 December) ships Qt Script unchanged, still on a JavaScriptCore snapshot of 27 January 2011, while QML gets V8 and the new QJSEngine class in the Qt QML module takes over the role of embeddable JavaScript engine. MuseScore announces in July that its QtScript plugin framework will be replaced by QML because Qt 'does not maintain this anymore and it will not be available for the next major Qt version'. Digia acquires all rights to Qt from Nokia
2015
Qt 5.5 (tagged 1 July 2015) formally deprecates Qt Script together with Qt WebKit and Qt Declarative (Qt Quick 1): 'These modules are still included in the Qt 5.5 release, but considered for removal in the future releases of Qt.' The module documentation gains its warning that it 'is not actively developed' and 'is provided for backwards compatibility with Qt 4 only'
2020
Qt 5.15 LTS (26 May) is the last feature release to include Qt Script; 5.15.2 (13 November) is the last release before the branch goes commercial-only. Qt 6.0 (8 December 2020) lists Qt Script and Qt Script Tools among the 'Removed Modules in Qt 6.0'
2021-2025
The 5.15 branch continues as commercial-only LTS patch releases (v5.15.3-lts, 3 March 2021, with LGPL source tags following about a year later) whose changes to Qt Script are version bumps; the last real code change is of 26 October 2021. Applications migrate: qbs 2.0 (30 March 2023) swaps QtScript for QuickJS, Stellarium 1.0 (1 October 2022) and Amarok 3.0 (April 2024) move to QJSEngine. The final tags are v5.15.19-lts (19 May 2025), v5.15.18-lts-lgpl (31 October 2025) and v5.15.19-vxworks-lts (18 December 2025); Debian 12 (5.15.8), Ubuntu 24.04 (5.15.13) and Debian 13 (5.15.15) still package qtscript5-dev

Notable Uses & Legacy

QML and Qt Quick 1 (Qt 4.7-4.8)

The most consequential use was Qt's own: the QtDeclarative module that Qt 4.7 introduced in September 2010 evaluated QML's property bindings and JavaScript functions with a QScriptEngine on the JavaScriptCore back-end (the Qt 4.8 engine header includes QtScript/qscriptengine.h). Every Qt Quick 1 application - including those written for Nokia's Symbian and MeeGo phones - therefore ran its logic on QtScript until Qt 5 gave QML the V8 and then V4 engines

Amarok 2 (KDE music player)

Amarok 2.0 (December 2008) rebuilt its scripting on QtScript with the Qt Script Generator bindings ('QtBindings support for the scripts', its ChangeLog records), so lyrics fetchers, internet-radio services and, from Amarok 2.2, context-view applets were written in JavaScript against Amarok.Playlist, Amarok.Engine and similar objects. Wikipedia's QtScript article uses it as the canonical example. The engine 'has been ported from QtScript to QJSEngine' in the Amarok 3.0 cycle (2.9.82 beta, April 2024), with the ChangeLog admitting that 'previous scripts are often not compatible'

KDE Plasma 4 desktop

Plasma's 'Simplified JavaScript' plasmoid API, which KDE TechBase documents as 'powered by Qt's QtScript system', let desktop widgets be written in JavaScript without a compiler; the engine moved into kdebase/runtime in KDE 4.3 (August 2009) and KDE SC 4.4 (February 2010) opened plasmoid development to QtScript, with Aaron Seigo's 'JavaScript Jam' contest to promote it. Later Plasma 4 releases also used the engine for desktop-layout scripts. Plasma 5 replaced this with QML and QJSEngine

Stellarium planetarium

Stellarium 0.10.1 (February 2009) replaced its home-grown StratoScript with a scripting feature 'based on the Qt Scripting Engine', in which ECMAScript scripts drive the sky view through slots on the StelMainScriptAPI object - the show-and-tell scripts bundled with every release are written in it. The QtScript module (under Qt 4, then Qt 5) was used from 0.10.1 to 0.22 (2022); the Qt 6-based Stellarium 1.0 of October 2022 ported StelScriptMgr to QJSEngine, and its class documentation keeps 'Notes on migration from QtScript to QJSEngine'

MuseScore 1.x plugins and qbs

MuseScore's first plugin system (in the 0.9.x and 1.x releases, up to 1.3 in 2013) was QtScript with generator-made Qt bindings - '> 1100 files with > 297000 lines of code' of bindings, as the project's July 2012 announcement of the QML replacement complained. Qt's own build tool qbs (first commit February 2012, 1.0 in May 2013) executed the JavaScript in its project files on QtScript for eleven years, until qbs 2.0 (30 March 2023) 'switched JavaScript engine from QtScript to QuickJS'

Daz Studio

Daz 3D's scripting reference records the two generations of Qt scripting in one commercial product: Daz Script 1 was based on QSA, and when Trolltech ended QSA, Daz Script 2 was rebuilt on Qt Script's ECMA-262 compliance; Daz Studio 4.0.x was built on Qt 4.7 and 4.5+ on Qt 4.8, and the company points its script authors at Qt's 'Moving from QSA to Qt Script' document

Language Influence

Influenced By

ECMAScript JavaScript QSA (Qt Script for Applications) C++

Influenced

QML QJSEngine (Qt QML) Daz Script

Running Today

Run examples using the official Docker image:

docker pull
Last updated: