VBScript (6.0)

This assessment applies the coupling account — coupling as access to a shared resource, and the coupling floor [1], [2] — and the knowledge-embodiment theorem [3]; the language is assessed against its official reference [4].

1 Assessment

This page assesses VBScript in five parts: core coupling — what the language’s own constructs force; ecosystem coupling — what the surrounding platform, tooling, and community cost; engineering readiness — whether the artifact can be reproduced, verified, observed, worked in quickly, connected to other languages, and governed openly; the profile — the unscored facts a score cannot express; and the scoring detail — the mechanism marks and the arithmetic behind every score. A ✅ bullet marks a construct that helps. A ⚠️ or ❌ bullet marks a cost; the scoring model does not price every cost named here.

Core coupling 40/100 · Ecosystem coupling 39/100 · Engineering readiness 57/100

1.1 Core coupling

1.1.1 Type

  • ❌ A variable has no declared type: Dim x declares a name, and the value it holds is a Variant whose subtype is decided at the assignment, so the operator resolves the operands when the statement runs and + adds or concatenates according to the values it receives (T1)
  • ❌ There is no namespace: Every global variable and procedure lives in one flat global scope, so two included scripts share it (T6)
  • ❌ There is no module boundary: A script file exports nothing and imports nothing explicitly, and ExecuteGlobal or a .wsf include writes into the same global scope (T11)
  • ✅ The subtype is inspectable: VarType, IsNumeric, IsDate, IsArray, and IsObject let a script ask what a variant holds
  • ✅ Null and Empty are distinct values with their own tests: IsNull and IsEmpty separate a true null from an uninitialised variant
  • ✅ Class, added in version 5.0, groups state with behaviour: A class declares Private fields and Public property procedures, with Class_Initialize and Class_Terminate

1.1.2 Construction

  • ❌ A global variable appears at its first assignment: Without Option Explicit, x = 1 at file scope creates a global, so state appears wherever a name is first used (C1)
  • ✅ Option Explicit requires a declaration: With it, an undeclared name is an error instead of a new variable
  • ✅ Sub and Function scope their own locals: A Dim inside a procedure belongs to that procedure
  • ✅ A class validates and cleans up in its two lifecycle methods: Class_Initialize runs at creation and Class_Terminate at release
  • ✅ A .wsf file combines several scripts: A Windows Script File includes more than one script file, and the procedures of one are callable from another
  • ⚠️ ExecuteGlobal defines a global at run time: A generated statement can create a name that no declaration lists

1.1.3 Memory

  • ✅ The script engine owns the memory: There is no allocate, free, or pointer operation in the language
  • ✅ A COM object is released by reference count: The object is freed when its last reference goes out of scope, and Class_Terminate runs at that point
  • ✅ No pointer type and no address exist: A value can never name a memory location
  • ✅ A class instance is collected by the engine: The script states no lifetime for a class object
  • ⚠️ A reference cycle between script and COM objects is not reclaimed: The engine’s counter cannot release a cycle, and the process must end to reclaim it
  • ⚠️ Repeated string concatenation in a loop reallocates: A long string built with & is copied at each step, and the language has no string builder

1.1.4 Error

  • ❌ There is no structured error path: The language has no try and no catch, only On Error Resume Next and the Err object (Er1)
  • ❌ On Error Resume Next discards a failure by default: The next statement runs regardless, and the failure is invisible unless Err.Number is tested
  • ✅ The Err object makes a failure a value: Err.Number, Err.Description, Err.Source, and Err.Raise let a handler read and create a failure
  • ✅ On Error GoTo 0 ends the suppressed mode: Error handling returns to the default at that statement
  • ⚠️ A host error names its provider: An ADO, WMI, or file-system failure carries a provider-specific number and source, so a handler is bound to that provider
  • ⚠️ An unhandled failure ends the script: There is no caller frame to unwind to, and the default action is to stop

1.1.5 Concurrency

  • ✅ The language has no shared-memory concurrency: A script runs single-threaded in its host, so there is no race to guard
  • ✅ A script can start another process: WScript.Shell.Run launches a program, and Exec returns a stream of its output
  • ✅ The host delivers an event to the script on its own thread: A callback is serialised onto the host’s thread, so the script never observes a concurrent invocation of itself
  • ⚠️ The host decides the threading model: Windows Script Host, Internet Explorer, and classic ASP each run a script differently, and the host’s apartment model governs a COM call
  • ⚠️ A session-scoped object is shared across requests: In classic ASP, Session state is visible to more than one request, and nothing in the language partitions it
  • ⚠️ A long-running script blocks its host thread: The language has no yield and no cancellation

1.1.6 Platform

  • ❌ The engine is Windows-only: vbscript.dll is the only implementation, and it ships with Windows, so a script runs on no other platform (P1)
  • ❌ Every capability arrives through COM: File access, WMI, ADO, and the shell are COM objects such as Scripting.FileSystemObject and ADODB.Connection, so a script depends on the registered object model
  • ✅ A .vbs file needs no build step: The host runs the text as written
  • ✅ The host is part of the operating system: cscript.exe and wscript.exe are installed with Windows
  • ⚠️ The host decides which objects exist: Windows Script Host, Internet Explorer, and classic ASP present different object models to the same language
  • ⚠️ A .wsf file states its own includes: A multi-file script needs the Job attributes and the <script src=...> elements that name its parts

1.1.7 Trade-offs (not coupling)

  • Hosted scripting is the purpose of the language: VBScript is designed to be embedded in a host, so the dependence on the host is a scope decision
  • The classic Visual Basic surface is a familiarity trade: The BASIC syntax is easy to read, and one value type keeps the engine simple, at the cost of the type system
  • A suppressed error is sometimes deliberate: On Error Resume Next around one statement is a chosen tactic
  • The language is meant for short programs: A page of automation is the design point, not a system
  • A fixed parameter list is a deliberate omission: The language cannot pass a variable number of arguments, so a variadic call is written as an array parameter
  • The deprecation is a lifecycle decision: Microsoft’s removal plan is a product decision rather than a language mechanism

1.2 Ecosystem coupling

1.2.1 Performance

  • ⚠️ The compiled form does not survive the process: The engine compiles the script at load rather than ahead of time, so a fresh host pays the parse again
  • ⚠️ A variant costs at every operation: An operation reads the subtype tag and converts the operands before it acts
  • ✅ The engine is an in-process library: The host loads it once, so a script starts with no separate runtime to launch
  • ✅ The engine compiles the file before it runs: The host parses and compiles the script once at start, and a page host can keep the compiled script for later requests
  • ⚠️ A COM call dominates a data-heavy script: The crossing into ADO, WMI, or a file-system object is where the time goes
  • ⚠️ String handling is the common trap: Concatenation in a loop and a repeated RegExp replace on a large string cost far more than the control flow

1.2.2 Ecosystem

  • ❌ The language is proprietary and discontinued: It exists in one vendor’s product, and Microsoft announced the deprecation in October 2023 (Ec4)
  • ❌ The ecosystem is legacy and frozen: The language has gained no feature since version 5.5 (2000), when the engine moved to sustaining engineering, so the tool field is historical (Ec3)
  • ✅ The runtime tooling is part of Windows: cscript and wscript are installed with the operating system
  • ✅ A large body of published scripts exists: Administrative scripts, examples, and books from the 2000s are widely available
  • ✅ The migration targets are named and documented: Microsoft points to PowerShell and JavaScript and describes the path
  • ⚠️ Many environments block the script host: A security policy or a mail filter commonly disables or rejects a .vbs file

1.2.3 Evolution

  • ❌ The language is discontinued: Microsoft announced the deprecation in October 2023 with removal planned after 2027, so no further version is expected (V3)
  • ✅ The remaining life is long and published: The phased plan keeps the language available as an on-demand feature for years, so an existing script keeps running
  • ✅ The language does not change under a script: An existing script’s meaning is fixed, which makes a migration predictable
  • ✅ A successor covers each use: PowerShell replaces the administration role and JavaScript replaces the browser and page role
  • ⚠️ New code has no reason to choose it: The direction of the platform is removal, not extension

1.2.4 Domain

  • ❌ The domain is Windows administration and COM: The useful work is expressed through WMI, ADO, the file-system object, and the shell, and none of that exists off Windows (D1)
  • ✅ Administrative automation fits it well: A short script drives WMI and the registry directly
  • ✅ Classic ASP and HTML Applications were real hosting domains: A server page and an .hta file both used VBScript with the full object model
  • ✅ Test automation still uses it: UFT One and similar tools keep a VBScript dialect for their test scripts
  • ⚠️ PowerShell has replaced it for administration: The same task is now written in PowerShell
  • ⚠️ An embedded operator interface is a narrow remaining use: A few industrial and point-of-sale systems still run a VBScript engine for local automation

1.2.5 Learning

  • ✅ The syntax is small: If ... Then ... End If, Sub, Function, and For Each are the surface
  • ✅ The curve is gentle for a Visual Basic programmer: The classic Visual Basic surface carries over almost unchanged
  • ✅ The reference is complete: Microsoft’s VBScript Language Reference documents every statement and function
  • ✅ The error model is easy to start with: On Error Resume Next and the Err object are a few lines
  • ⚠️ The real subject is COM: The object model beneath the language is the large part of the work
  • ⚠️ The error model is easy to misuse: It requires a discipline that the language does not enforce

1.2.6 Syntax

  • ✅ The keywords are words: If, Then, Else, End If, For Each, and Next
  • ✅ A line is a statement: Statement boundaries are lines, and : separates two statements on one line
  • ✅ Line continuation is explicit: _ continues a statement on the next line
  • ✅ A block closes with its keyword pair: End If, End Sub, End Function, Loop, and Next each close their own construct
  • ⚠️ The language is case-insensitive: myValue and MyValue name the same variable, so a rename is not caught by the case
  • ⚠️ Dim may be omitted: Without Option Explicit, a name is declared by its first use, so a typo reads as a new variable

1.2.7 Testing

  • ❌ There is no test framework in the language or the host: A check is a script that compares values and reports the result (G1)
  • ✅ A test is a .vbs file run by cscript: The same engine runs the test and the code under test
  • ✅ A harness is only a few lines: WScript.Echo with a comparison gives a report, and a failing check can call Err.Raise
  • ✅ cscript //X starts the script debugger: A step-through debugger is available where the Windows debugging tools are installed
  • ⚠️ A test suite is the programmer’s own: There is no runner, no fixture loader, and no report format
  • ⚠️ A type error appears only in the test run: Nothing checks a value’s use before the line executes

1.2.8 Security

  • ❌ Untrusted input can become code: Execute, ExecuteGlobal, and Eval evaluate text, so a value built from input can run as a statement (Q3)
  • ❌ Script malware is a known, historical class: The ILOVEYOU worm spread as a .vbs attachment, and the file extension is still commonly blocked
  • ❌ The file-system object grants the user’s own rights: Scripting.FileSystemObject can read or overwrite any file the invoking user can
  • ✅ A script runs without elevation by default: It holds the privileges of the invoking user and no more
  • ⚠️ The usual mitigation is policy: A mail filter, an attachment block, or a group-policy restriction, rather than a language feature
  • ⚠️ Correct quoting must be uniform: An injection that forms a valid statement is not distinguishable from a legitimate one by the engine

1.3 Engineering readiness

1.3.1 Reproducibility

  • ✅ No charged mechanism in this dimension.

1.3.2 Supply chain

  • ⚠️ Published packages carry no signed provenance by default.

1.3.3 Observability

  • ⚠️ No stable tracing and metrics standard.
  • ⚠️ The standard library has no structured logging.

1.3.4 Feedback

  • ⚠️ No fast in-editor analysis.

1.3.5 Interop

  • ⚠️ No maintained portable target.

1.3.6 Governance

  • ⚠️ One vendor decides the language’s direction.
  • ⚠️ The specification is not public.

1.4 Profile

Unscored, and kept separate from every score on purpose. The profile records what a mechanism price cannot express: what a running program costs, how well a coding model and an agent work in the language, and whether a safety-critical path exists.

1.4.1 Energy and cost

What this axis asks: what does a running program cost in energy and time?

  • ⚠️ Runs on a virtual machine, above native code in the energy and time benchmarks [5]; a causal re-analysis attributes most of the gap to execution time [6].

1.4.2 AI and agent readiness

What this axis asks: how well does a coding model and an agent work in this language?

  • ❌ Sparse training data: models write it unreliably [7].

1.4.3 Safety certification

What this axis asks: is there a certified or standards-qualified path to a safety-critical system?

  • ⚠️ No certified or standards-qualified path for safety-critical systems.

1.5 Scoring detail

1.5.1 Core coupling Dimensions

Dimension Mechanism Description Present Cost
Type T1 dynamic no static check ✅ −15
T2 weak static — 0
T3 dynamic/duck dispatch — 0
T4 no sum types — 0
T5 no generics — 0
T6 no namespaces ✅ −8
T7 type erasure/reflection — 0
T8 operator overloading — 0
T9 inheritance required for polymorphism — 0
T10 no null-safety — 0
T11 no module boundary ✅ −8
T12 no effect tracking ✅ −8
T13 async/sync colouring — 0
T14 unchecked foreign boundary ✅ −4
Type subtotal −15 (−43)
Construction C1 global mutable state by default ✅ −15
C2 no immutability by default — 0
C3 constructors coupled to allocation — 0
C4 no constructor/validation — 0
Construction subtotal −15
Memory M1 manual deallocation — 0
M2 GC non-deterministic pauses — 0
M3 no RAII — 0
M4 no ownership model — 0
Memory subtotal 0
Error Er1 no structured path ✅ −15
Er2 unchecked exceptions only — 0
Er3 errors ignored/non-exhaustive — 0
Er4 no composable result type — 0
Error subtotal −15
Concurrency K1 GIL/no parallel — 0
K2 shared mutable state default — 0
K3 manual sync no race detection — 0
K4 no structured concurrency — 0
K5 no primitives — 0
Concurrency subtotal 0
Platform P1 cannot function outside one vendor/domain ✅ −15
P2 single-vendor but other uses — 0
P3 legacy/discontinued platform — 0
Platform subtotal −15

Core Dimensions score: 40/100 — total cost = −60 (per-dimension subtotals are capped at −15; an uncapped cost is shown in parentheses where the cap bites).

1.5.2 Ecosystem coupling Dimensions

Dimension Mechanism Description Present Cost
Performance R1 interpreted no AOT/JIT — 0
R2 GC pauses — 0
R3 JIT warmup — 0
Performance subtotal 0
Ecosystem Ec1 no package manager — 0
Ec2 fragmented tooling — 0
Ec3 small/niche/discontinued ✅ −8
Ec4 proprietary ✅ −8
Ec5 platform-locked tooling — 0
Ec6 monoculture — 0
Ec7 legacy burden — 0
Ecosystem subtotal −15 (−16)
Evolution V1 breaking changes — 0
V2 frozen — 0
V3 discontinued ✅ −15
V4 glacial standards — 0
Evolution subtotal −15
Domain D1 domain/vendor lock-in ✅ −15
D2 poor domain fit — 0
D3 framework forces architecture — 0
Domain subtotal −15
Learning L1 steep — 0
L2 large surface/multi-paradigm — 0
L3 sparse docs — 0
Learning subtotal 0
Syntax S1 verbose — 0
S2 inconsistent — 0
S3 punctuation-heavy — 0
Syntax subtotal 0
Testing G1 weak tooling ✅ −8
G2 poor debugging — 0
G3 runtime-only errors — 0
Testing subtotal −8
Security Q1 memory-unsafe — 0
Q2 dynamic/weak typing risk — 0
Q3 known vulnerability/injection ✅ −8
Security subtotal −8

Meta Dimensions score: 39/100 — total cost = −61 (per-dimension subtotals are capped at −15; an uncapped cost is shown in parentheses where the cap bites).

1.5.3 Engineering readiness Dimensions

Dimension Mechanism Description Present Cost
Reproducibility Y1 build not reproducible — 0
Y2 dependencies not pinned — 0
Reproducibility subtotal 0
Supply chain Y3 no signed provenance ✅ −8
Y4 registry without namespacing — 0
Supply chain subtotal −8
Observability Y5 no stable tracing standard ✅ −8
Y6 no structured logging ✅ −4
Observability subtotal −12
Feedback Y7 slow build — 0
Y8 no fast in-editor analysis ✅ −4
Feedback subtotal −4
Interop Y9 no foreign-function interface — 0
Y10 no portable target ✅ −4
Interop subtotal −4
Governance Y11 single-vendor governance ✅ −8
Y12 closed specification ✅ −8
Governance subtotal −15 (−16)

Readiness Dimensions score: 57/100 — total cost = −43 (per-dimension subtotals are capped at −15; an uncapped cost is shown in parentheses where the cap bites).

Verdict: VBScript holds the lowest pair of scores in this group, and the losses concentrate in its defaults and its dependence. A variable is a Variant with no declared type, an undeclared name becomes a global, an error is a mode the caller must enable, and every useful capability arrives through a COM object that exists only on Windows. What the language does provide is a tiny readable syntax, a host that is already installed, lifecycle methods on a class, and Option Explicit to require a declaration. Main strengths: a gentle learning curve, direct WMI and ADO automation, a .wsf file that packages a multi-file script, and a simple way to restrict a script through the Windows Script Host. Main weaknesses: no structured error path, no namespace and no module boundary, a proprietary and discontinued implementation, a domain locked to Windows and COM, weak tooling, and an injection surface that made it a malware vehicle.


The formal development. The definitions, theorems, and proofs behind this page are published in:

All published papers

References

[1]
Y. Loth, “On the nature of coupling: All coupling as shared resource access.” Zenodo, Aug. 2026. doi: 10.5281/zenodo.21925122.
[2]
Y. Loth, “Coupling as a consequence of cohesion: Decomposition, the coupling floor, and domain-imposed coupling.” Zenodo, Aug. 2026. doi: 10.5281/zenodo.21925201.
[3]
Y. Loth, “On the nature of cohesion: Cohesion as correctness relative to a partitioning rule.” Zenodo, Jul. 2026. doi: 10.5281/zenodo.21703193.
[4]
[5]
R. Pereira et al., “Energy efficiency across programming languages: How do energy, time, and memory relate?” in Proceedings of the 10th ACM SIGPLAN international conference on software language engineering (SLE), 2017, pp. 256–267. doi: 10.1145/3136014.3136031.
[6]
N. van Kempen, H.-J. Kwon, D. T. Nguyen, and E. D. Berger, “It’s not easy being green: On the energy efficiency of programming languages,” in Proceedings of the 40th IEEE/ACM international conference on automated software engineering (ASE), 2025. doi: 10.1109/ASE63991.2025.00131.
[7]
S. Joel, J. J. Wu, and F. H. Fard, “A survey on LLM-based code generation for low-resource and domain-specific programming languages,” ACM Transactions on Software Engineering and Methodology, 2025, doi: 10.1145/3770084.