twinBASIC Update: October 6, 2026

Highlights include ~43x compile-time improvements for certain kinds of twinBASIC projects.

twinBASIC Update: October 6, 2026

On April 23, 2021, I helped Wayne Phillips introduce the world to twinBASIC at the Access DevCon Vienna conference. I boldly predicted that twinBASIC (along with the Monaco editor) would replace VBA and its outdated development environment by 2025. (And I was oh so close...) With that goal in mind, this weekly update is my attempt to keep the project fresh in the minds of the VBA development community.

Every Sunday Monday week, I will be providing updates on the status of the project, linking to new articles discussing twinBASIC, and generally trying to increase engagement with the project. If you come across items that should be included here, please leave a comment below.

Here are some links to get involved with the project:


Highlights

Compile Performance Boost for Large Projects

The BETA 996 release includes the following understated release note:

improved: made some llvm adjustments to reduce excessive compile times and memory use during compilation

So what kind of performance increase are we talking about here? How about a 43x improvement!

BETA 995 compile time for XYplorer with LLVM:  33mins, 12GB RAM peak (12 threads) BETA 996 compile time for XYplorer with LLVM:  46 secs, 600MB RAM peak (12 threads). For those projects with any huge monolithic procedures, big improvement.

Note that 43x improvement is almost certainly atypical. The final sentence above hints strongly at that:

For those projects with any huge monolithic procedures, big improvement

It would seem projects with those characteristics are likely to benefit the most.

Discord Chat Summary

* Auto-generated via Claude Sonnet 5.5

Overview

This week, twinBASIC's General and Docs channels were dominated by the LLVM backend, with major performance gains and a huge compile-time fix in BETA 996. The Docs channel focused on okas_o's documentation and validation tooling, which exposed compiler bugs and fed new IDE add-ins. Engagement was high across both channels, with waynephillipsea responding directly to bug reports, design questions and extensibility requests.

LLVM Backend & Performance (Beta/Experimental)

  • Benchmarks: wqweto's crypto project shows LLVM speedups of about 3.3x–12.8x (32-bit) and 4.4x–15.4x (64-bit) over pre-LLVM builds. The 32-bit build now matches or beats VB6 native on every algorithm measured, and GHASH is the only draw.
  • Compile time: waynephillipsea reports XYplorer's LLVM compile dropped from 33 minutes and 12GB RAM peak (BETA 995) to 46 seconds and 600MB (BETA 996). Projects with huge monolithic procedures benefit most.
  • Known gaps: waynephillipsea says error propagation, such as Err.Raise, is the one big unsupported item in LLVM builds, though local handlers should catch errors. wqweto also hit an x64 crash and an ACCESS_VIOLATION when enabling LLVM in the DEBUG compiler options.
  • Resources: Compile RAM depends on the project and thread count, and some single-threaded compiles need only about 500MB.

Language Features & VB6 Parity

  • Loop unrolling (BETA 997): waynephillipsea chose an intrinsic that compiles to a no-op but hints LLVM, instead of an attribute, because [...] is already valid VBx syntax in procedures. It gave about +10% on wqweto's MD5 over LLVM defaults. okas_o has already documented it.
For i = 0 To 64
   Compilation.UnrollLoop(4)
   DoSomething(i)
Next
  • Friend method performance: VanGoghGaming's benchmark shows VB6 calls Friend methods about 15x faster than Public ones (13ms vs 185ms). tB currently times them identically. waynephillipsea says it would work like UnprotectedAccess(classInstance).Method() and is low priority.
  • Calling conventions: The new ThisCall and FastCall conventions are now documented. fafalone uses FastCall declarations in WinDevLib for ntdll byte-swap functions on newer builds, with a conditional fallback for older ones.
  • Smaller notes:
    • NotDispatchable removes the IDispatch vtable entries and forces early binding, but it doesn't change executable size.
    • tB's right shift is signed, as in C/C++, and an unsigned >>> was suggested.
    • DISPID_EVALUATE for [A1]-style Excel evaluation has an open issue.

IDE Bugs & Compiler Internals

  • Ctrl-R / Project Explorer bug: waynephillipsea traced the intermittent empty object view and compiler restarts to a stray BSTR freed as a C buffer. This followed his overhaul replacing nearly all compiler BSTRs with length-prefixed C buffers. The fix landed in BETA 994, and one reporter confirmed it.
  • Compiler internals only: waynephillipsea says the BSTR change doesn't affect the tB runtime. He cites OS side-data overhead, cross-platform readiness and precise debug-build memory tracking as the reasons.
  • Debugger and migration: "Run to cursor" isn't implemented yet, and wqweto reports flaky breakpoints. VBP migration now handles LinkSwitches=/SUBSYSTEM:CONSOLE, and fafalone asked for /SUBSYSTEM:NATIVE for VB6 driver projects.
  • Bug-report guidance: waynephillipsea says no special format is needed. Hard-to-reproduce reports are good candidates for TwinSight, the AI tooling that researches issues on its own.

Documentation & Validation Tooling

  • New docs: okas_o added pages for calling conventions, IEnumVARIANT, IUnknown, IDispatch, ISupportErrorInfo/IErrorInfo, IConnectionPointContainer/IConnectionPoint, graphics methods (Line, Circle, PSet, Scale) and the BETA 997 intrinsics.
  • Attribute validation: After VanGoghGaming reported that ComExport was documented as applying only to constants, okas_o cross-checked the Attributes page against real tB behavior using machine-generated samples. That was the only gap found. ComExport's main purpose is exporting API declarations into an ActiveX DLL's TypeLib.
  • Bugs found: The docs build work surfaces real compiler issues, tracked in a BUGS-TO-REPORT.md list. They include an undiagnosed interface cycle that makes Build silently do nothing, and a compiler crash when required empty folders are missing. The impexp tool now adds those folders on import.
  • Goal: okas_o wants the docs to describe exactly what tB does, and treats any divergence from VBx as a bug to fix.

IDE Add-ins & Extensibility (Experimental)

  • Help add-in: Pressing F1 on a keyword like MsgBox opens documentation in the IDE's help window. It now respects [Description] and strips the website chrome. The ~25MB DLL bundles its content and a small web server, so it works offline.
  • API requests: okas_o asked for the IDE server to ignore URL query strings, and proposed AddStaticServerPath and RemoveStaticServerPath. waynephillipsea called these "doable for sure", and okas_o will write a design proposal.
  • WDL auto-import add-in: okas_o is prototyping an add-in that indexes WinDevLib and writes only the declarations a project uses into a single file. This keeps .twinproj files self-contained without embedding the whole package.
  • Git and .twinproj: okas_o expects to release a virtual-filesystem layer within a week. It lets Git see and merge the individual files inside a .twinproj, which answers a team-workflow concern raised by franic1456. okas_o is also building a JS-based tB interpreter so docs examples can run in the browser.

Community Projects & Support

  • fafalone's RichEdit control: It adds spellcheck with wavy underlines, suggestions and autocorrect, using an undocumented temporary-underline trick. Direct2D printing and print preview are in, so color emoji won't print in grayscale. Touch-keyboard support uses an accessibility proxy, and SF_HTML or tomConvertHtml enables HTML export. The flash-last-character password feature turned out never to be implemented by Microsoft.
  • WinDevLib: fafalone reported slow package-server downloads. An apparent error on another user's end was caused by not installing the main package that the "WinDevLib for Implements" add-on depends on. He also confirmed that IEnumConnectionPoints lacking a tb prefix is a bug, per waynephillipsea.
  • Project info:
    • Fusion targets OCX controls, not ActiveX DLLs.
    • The IDE stays 32-bit for now, and v1 will likely offer both 32-bit and 64-bit versions.
    • Unsigned releases are attributed to the one-year business-history requirement for signing.

Conclusion

LLVM is maturing quickly, and BETA 996 removes the worst compile-time problem. Error propagation is the main remaining gap, and the loop-unroll intrinsic is the first of several planned optimizer hints. Documentation work and community projects such as the RichEdit control, the help add-in and the WDL tooling are closing the gaps in docs, IDE workflow and VB6 parity. With waynephillipsea open to new extensibility APIs and low-priority items like Friend method optimization queued, the project is moving toward its v1 goals.

Around the Web

Nothing noteworthy this week.

Changelog

Here are the updates from the past week. You can also find this information by visiting the GitHub twinBASIC Releases page.

Releases · WaynePhillipsEA/twinbasic
Contribute to WaynePhillipsEA/twinbasic development by creating an account on GitHub.

AI-Generated Changelog Summary

* Auto-generated via Claude Sonnet 4.6, sorted in order of its opinion of "most impactful changes."

twinBASIC changelog summary

  • New language features: Global array constants are now supported, for example Const Something() As Long = Array(1,2,3,4). This works for single-dimension arrays of simple types only. New intrinsics cover bit shifting and rotating (ShiftRotateLeft, ShiftRotateRight, ShiftUnsignedRight) and byte swapping (ByteSwap).

  • Performance control: The new Compilation.UnrollLoop intrinsic hints to LLVM that a loop should be unrolled for speed. LLVM builds also use less memory and compile faster, and they now ignore Debug.Assert statements.

  • LLVM build reliability: Variant array element access no longer fails or crashes on x64 LLVM builds. An edge case when calling Delegates is fixed. ActiveX DLL projects now show a progress bar and compile multi-threaded instead of appearing frozen.

  • Data-loss fix: Export Project no longer follows directory junctions when it clears the output folder. Before, it could delete files outside the export folder.

  • Compiler and IDE crash fixes: The compiler no longer crashes on a malformed Interface ... Extends definition or a [PopulateFrom] attribute with no arguments. It also no longer crashes when a package is missing its Packages folder, when you switch to Object-View, when Global Search has "Exclude Comments" ticked, or when compiling the CEF sample. Some error messages that showed position [1,1] now show the correct location.

  • Runtime crash fixes: Forms(index) no longer returns a broken reference that later crashes the process. For Each over WebView2 headers no longer crashes. The IEnumConnections and IEnumConnectionPoints enumerators now follow the COM contract.

  • VB6/VBx compatibility: FileCopy now matches VB6 behavior. Circle now checks the maximum allowed angle for Start and End. Several regressions are fixed:

    • As New now accepts a constructor whose arguments are all Optional.
    • As New now works with [COMCreatable(False)] classes.
    • StrConv with vbProperCase works again.

    VBP migration also gained support for LinkSwitches=/SUBSYSTEM:CONSOLE and no longer errors on the icon-form setting.


WARNING: The following issues are present in each of the releases below:

  • IMPORTANT: This is a BETA release under active development. It is not recommended for production use.

BETA 993

  • fixed: (regression) Global Search addin causes a crash-restart in the compiler process if 'Exclude Comments' is ticked [ Jim Mack, discord ]
  • fixed: (regression) compiling the CEF sample project causes a compiler crash [ ronald, discord ]
  • fixed: edge case LLVM compilation issue when calling Delegates
  • fixed: classes with [COMCreateable(False)] set on them cannot be used as an As-New datatype [ VanGoghGaming, discord ]
  • fixed: some error diagnostics showing with a position of [1,1] instead of the correct document position

BETA 994

  • fixed: accessing a Variant array element could fail or crash at runtime when using LLVM on x64 builds
  • fixed: crash when switching to Object-View in PROJECT EXPLORER [ VanGoghGaming, discord ]

BETA 995

  • fixed: correction to the trigger for the As-New error diagnostic introduced in BETA 993 [ Krool, discord ]
  • fixed: LLVM builds now ignore Debug.Assert statements [ wqweto, discord ]

BETA 996

  • added: VBP migration support for LinkSwitches=/SUBSYSTEM:CONSOLE [ wqweto, discord ]
  • fixed: VBP migration error for project.iconForm setting when no icon form is set and the startup object is set to "Sub Main"
  • improved: made some llvm adjustments to reduce excessive compile times and memory use during compilation

BETA 997

  • added: intrinsic Compilation.UnrollLoop(Optional UnrollCount) to give LLVM a hint that you want a loop to be unrolled for performance reasons
  • added: intrinsic VBA.Math.ShiftRotateLeft
  • added: intrinsic VBA.Math.ShiftRotateRight
  • added: intrinsic VBA.Math.ShiftUnsignedRight
  • added: intrinsic VBA.Math.ByteSwap
  • added: support for global array consts Const Something() As Long = Array(1,2,3,4) syntax (single dimension scalar types only)
  • fixed: ActiveX DLL projects would not show a progress bar during LLVM compilation, falling back to single-thread compilation, with large projects appearing frozen due to slow build times [ kimpos, discord ]
  • fixed: Circle graphics method was not verifying the max allowed angle for Start/End args [#2463]
  • fixed: (regression) Forms.Item() accessor was returning an invalid object pointer in some circumstances [#2458]
  • fixed: (regression) a constructor with all Optional arguments was not being treated like a parameterless constructor for As-New verification purposes [#2459]
  • fixed: WebView headers runtime iteration issues [#2460]
  • fixed: IEnumConnectionPoints iterator implementation issue [#2462]
  • fixed: IEnumConnections iterator implementation issue [#2461]
  • fixed: Export feature deletes through directory junctions during clearing of the output folder: [#2456]
  • fixed: compiler crash on malformed Interface-Extends definition [#2453]
  • fixed: FileCopy behaviours to match VBx [#2451]
  • fixed: malformed Enum [PopulateFrom] attribute without arguments causes compiler crash [#2450]
  • fixed: hovering over symbols that are declared as ByVal params produced an incorrect warning about Option-Explicit being off [#2448]
  • fixed: F1 toggle for signature help expansion in the IDE would trigger an error report in the DEBUG CONSOLE [#2446]
  • fixed: missing Packages folder within a package would cause a compiler crash on loading the project [#2442]
  • fixed: error details for some array subscript out of range errors [#2440]
  • fixed: (regression) StrConv with vbProperCase not working correctly [#2464]

All original code samples by Mike Wolfe are licensed under CC BY 4.0