An open, cross-platform IDE for Visual Basic 6 & VBA.
HexIDE reads and writes native .vbp/.frm/.bas/.cls files and layers on a modern,
LSP-backed editor — IntelliSense, diagnostics, code folding, rename, and formatting — over a
form designer and project manager. It runs on Windows, macOS, and Linux. No COM, no registry,
no Visual Studio required.
Status: Alpha — early developer preview. HexIDE is a working cross-platform VB6 editor and form designer. It is not a compiler — the built-in interpreter runs only a subset of VB6. File → Make packages a project with that interpreter as a standalone program; a native
.exestill needs an installed copy of the original VB6 (Windows only). Treat it as an early preview, not a finished product. Contributions and feedback are very welcome.Work on a copy. The file-format work has come a long way — all 22 of VB6's own template forms now survive a save byte-for-byte — but that corpus is Microsoft's templates, not your project. Anything hosting a third-party OCX is the known weak edge. See Opening real VB6 projects for exactly what it does and does not preserve.
Back it up first, or work on a copy, or at least commit before you open it.
That warning is measured, not boilerplate. The benchmark below is the 22 form and control files
Visual Basic 6 ships inside its own VB98\Template folder — Microsoft's files, written by VB6
itself. If HexIDE cannot re-emit those unchanged, it cannot re-emit yours.
| Against VB6's own 22 template forms | Today |
|---|---|
| Open, edit code, and run | all 22 |
| Survive open-then-save byte-for-byte | all 22 |
| Open read-only — HexIDE refuses to save rather than damage them | 0 |
| Will save, but will not reproduce the original file | 0 |
The last three rows are two views of one thing, and that is the point: every VB6-authored form HexIDE is willing to save round-trips byte-for-byte, and a form it could not reproduce it would refuse outright. There is no longer a middle category — nothing saves lossily.
The last holdout was Web Browser.frm, whose six pictures sit on an MSComctlLib.ImageList, an OCX. Since
#60 those pictures are carried through a save with the block
that cites them, and the form round-trips byte-for-byte, its companion file included.
VB6's own project files (.vbp) round-trip byte-for-byte as well. So do standard and class modules
(.bas, .cls) — all three are covered by regression gates that fail the build if that stops being true.
Why forms are gated. A form HexIDE cannot reproduce opens read-only, with a banner saying so, and Save is refused. Refusing is recoverable; silently writing a file that only fails weeks later when you go back to VB6 is not. The reasoning is written up in docs/serialization-outcomes.md.
That count was 12, then six, and is now one. Menu trees started surviving a round-trip, which freed
VB6's six menu templates. Container nesting followed: a control inside a Frame or a PictureBox is
recorded on the model, written back nested, hosted by its container when the form runs, and drawn inside
it in the designer — which freed Options Dialog.frm and Tip of the Day.frm.
Then the companion-file model closed the rest. Button ListBox.frm and Mover ListBox.frm had been
saving lossily, dropping a control's picture reference while the .frx bytes survived on disk; the gate
learned to recognise that loss and refused them, and registering the properties that cite those blobs —
CommandButton.Picture and ListBox.DragIcon — made both reproducible instead. Treeview Listview Splitter.frm and Splash Screen.frm needed a VB.Image control class that did not exist. ODBC Log In.frm needed a .frx reader driven by the references in the form rather than a flat scan, because a
2-byte List/ItemData record is invisible to one.
The rule those six left under is the one the regression gate enforces: a form may only leave the read-only set by becoming reproducible, never by having its cause go unnoticed. A change that empties the set without OCX hosting behind it is a regression, not progress.
Companion binaries (.frx, .ctx, .pgx) are preserved, never regenerated. They hold icons,
pictures and list contents that exist nowhere else. When a form references a blob HexIDE does not
model, the save path leaves the companion file completely alone rather than rewriting it — an earlier
build regenerated them, which truncated one template's .frx from 790 bytes to 12 and deleted
another outright. Note the limit of that guarantee: the bytes are safe, but as above, the property
line in the .frm that points at them can still be dropped.
There is no autosave to your project files. Nothing is written to them until you save. HexIDE does keep a private copy of unsaved work every five seconds, and the next start offers it back after a crash (docs/crash-recovery.md). VB6 had no such safety net.
It is not a compiler. The built-in interpreter covers a subset of the language — enough to run
simple projects and demos, not enough to run a real application. File → Make writes a program
that runs on that same interpreter (see Making a program), so it runs what the
interpreter runs and no more. A native .exe comes from File → Make with VB6, which hands the
project to an installed copy of VB6 and is therefore Windows-only.
None of this is permanent. It is where a from-scratch reimplementation of a 1998 file format honestly sits today, and the gap is tracked file-by-file in docs/serialization-fidelity-2026-08.md.
HexIDE should feel instantly familiar to a VB6 developer — the same default keybindings, menus, and toolbars — with the dead weight of 1998 removed or modernised and modern conveniences folded in gently, never at the cost of familiarity. See PHILOSOPHY.md for the full statement.
- 🎨 Visual form designer — drag-and-drop controls on a Win98-style canvas
- 📦 Built-in controls — CommandButton, TextBox, Label, CheckBox, OptionButton, ComboBox, ListBox, Frame, PictureBox, Timer, Shape, Menu, HScrollBar, VScrollBar, and Image, which loads and runs but is not yet in the toolbox (#860); a project that references an in-box OCX library adds its implemented controls to the toolbox
- 💾 Native VB6 project format — reads
.vbp,.frm,.frx,.bas,.cls; writes.vbp,.frm,.bas,.cls(.frxcompanions are preserved as-is, not regenerated — see Opening real VB6 projects) - 🪟 MDI interface with dockable tool windows
- 💡 IntelliSense — keyword and declared-name completion as you type
- 📐 Code folding — Sub, Function, Property, If, For, Do, While, With, Select Case, Enum, Type and
#Ifblocks - 🔍 Find & Replace — modeless, with regex, whole word, match case, and scope options
- 🖌️ Format code (Shift+Alt+F) — keyword casing + auto-indentation, with format-on-save
- ⌨️ Auto-close blocks — type
Sub Foo(), press Enter, andEnd Subappears - 🔤 Keyword case-correction —
public subbecomesPublic Subon Enter - ⚙️ Tools ▸ Options — persistent editor, grid, and environment settings
- 🚨 Live diagnostics — syntax errors as red squiggles with hover tooltips
- 📝 Document symbols — two-combo procedure navigation (object + member)
- ✏️ Rename symbol (F2) — lexical rename across the current file
- 🎯 Go to Definition (F12) — jump to a declaration in the current file
Download from Releases. On Windows x64, start with
hexide-windows-amd64-setup.exe: it includes .NET, installs for all users into Program Files
(requires administrator approval), and adds a Start-menu shortcut and an uninstaller.
Portable archives remain available for every platform and processor.
Start with hexide-<platform>-selfcontained.*, which includes .NET. The smaller
hexide-<platform>.* build needs the plain .NET 10 Runtime
(Microsoft.NETCore.App) installed on every platform.
Linux: choose amd64 if uname -m prints x86_64, arm64 if it prints aarch64,
or arm for 32-bit Arm (armv7l), whose self-contained archive is hexide-linux-arm-selfcontained.tar.gz.
The archives have no top-level folder, so extract into a folder of their own. From the directory
containing your download (substitute arm64 or arm in the filename if needed):
mkdir -p ~/hexide
tar -xzf hexide-linux-amd64-selfcontained.tar.gz -C ~/hexide
~/hexide/HexIDESelf-contained builds still need native libraries, including the distro's libX11, libICE, libSM,
fontconfig and ICU. The v0.2.0 amd64 self-contained build started and showed the New Project dialog on
openSUSE Leap 16.0 with GNOME without adding any libraries; other distros, desktops and the Arm builds
were not checked.
That openSUSE install had no tar. If yours has none, these are alternatives:
- Python's
python3 -m tarfile -e hexide-linux-amd64-selfcontained.tar.gzextracted the archive there. To keep it in its own folder, usepython3 -m tarfile -e hexide-linux-amd64-selfcontained.tar.gz ~/hexide(the output-folder form is untested). - On openSUSE,
sudo zypper install tar(untested), then use the commands above. - Your desktop's Extract action (untested); choose a folder of its own.
On the same VM without a GPU, Avalonia used XWayland and fell back to software rendering. A GLX log
message saying the llvmpipe renderer is blacklisted is expected in that case; it did not prevent startup.
Windows portable: extract the .zip into its own folder and run HexIDE.exe.
The installer and portable builds are unsigned; SmartScreen shows a warning: More info → Run anyway.
macOS: extract in Terminal with tar -xzf <file>.tar.gz, then open HexIDE.app.
The builds are not notarised; Finder extraction applies a quarantine flag that the unsigned app cannot clear.
- .NET 10 SDK or later
- No Java required — the ANTLR4 grammar compiles via MSBuild
git clone https://github.com/hexide-io/HexIDE.git
cd HexIDE
# Build & run the desktop app
cd IDE
dotnet build HexIDE.Desktop/
dotnet run --project HexIDE.Desktop/
# Run the test suites, from IDE/ as above
dotnet test HexIDE.Runtime.Tests/ # VB6 interpreter
dotnet test HexIDE.Tests/ # IDE view-models
cd ../LspServer && dotnet test HexIDE.VbLspServer.Tests/ # LSP serverFile → Make writes your project out as a program that runs without HexIDE, and without .NET. The program is HexIDE's standalone runner, one self-contained file, renamed and placed beside your project's archive. Make needs that runner.
-
A download from Releases already has it, in the
standalonefolder beside the IDE. -
A build from source doesn't. Publish the runner into a
standalonefolder beside the IDE you run. For the IDE thatdotnet run --project HexIDE.Desktop/starts, fromIDE/:dotnet publish HexIDE.Standalone -f net10.0 -o HexIDE.Desktop/bin/Debug/net10.0/standalone/
The runner's project file publishes it single-file and self-contained, for the platform you publish on, so the command needs no other options.
If Make still says the runtime is missing, its message names the folder it looked in and the file it didn't find.
Programs made with v0.2.0 don't start, because that release's runner wasn't a single file (#1971). Make them again with v0.3.0 or later.
Open HexIDE.slnx at the repo root — the IDE and server projects and their tests, in two solution folders
(IDE and LspServer). Requires Visual Studio 2022 17.10+ for .slnx support.
HexIDE is a monorepo with a clean licence boundary:
HexIDE/
├── IDE/ # MIT — the IDE application
│ ├── HexIDE.Core/ # Framework-agnostic abstractions (no Avalonia)
│ ├── HexIDE/ # IDE shell, visual designer, code editor
│ ├── HexIDE.Runtime/ # VB6 interpreter & built-in controls
│ ├── HexIDE.Lsp/ # LSP client (StreamJsonRpc)
│ ├── HexIDE.Desktop/ # Desktop entry point
│ └── HexIDE.Standalone/ # Headless runner for published projects
│
├── LspServer/ # MIT — separate process (crash isolation)
│ └── HexIDE.VbLspServer/ # LSP server (proleap grammar + EmmyLua shell)
│
└── HexIDE.slnx # Master solution
The language features sit behind a standard LSP boundary — the IDE is only a client, and the server runs as its own subprocess for crash isolation. And the server is a replaceable backend, not a fixture — because the client is transport- and server-agnostic (it speaks only LSP JSON-RPC over a duplex byte stream, stdio on the desktop), a more capable language engine can take over language intelligence without any change to the IDE.
Under the hood, HexIDE.Core is a zero-dependency abstraction layer with no Avalonia
imports; Pure.DI provides source-generated, AOT-safe dependency injection; and theming is
driven by switchable theme packs (Classic, a Win98 style, ships with Dark and Abyss).
The server currently handles: initialize, didOpen/didChange/didClose, hover,
completion, signatureHelp, definition, documentHighlight, documentSymbol,
foldingRange, formatting, inlayHint, rename, and publishDiagnostics, plus HexIDE's own
vb/builtinSymbols.
HexIDE is under active development. Near-term work is client-side editor polish: richer hover and completion (docs + icons), inline rename and more themes.
Cross-file semantic analysis, project-wide navigation, and rename remain future work and need a dedicated language backend. The native interpreter debugger is available now, with breakpoints, stepping, Break, Immediate, Locals, Watches, and Call Stack.
Development happens in the open — see the issue tracker and Discussions to follow along or weigh in.
HexIDE would not exist without:
| Project | Author(s) | Contribution | Licence |
|---|---|---|---|
| AvaloniaVisualBasic6 | Bartosz Korczyński (@BAndysc) | The original IDE — form designer, component model, interpreter, project serialisation. HexIDE is a direct fork. | MIT |
| proleap-vb6-parser / grammars-v4 | Ulrich Wolffgang | The VB6 ANTLR4 grammar powering both the interpreter and the LSP server | MIT |
| EmmyLua.LanguageServer.Framework | CppCXY (the EmmyLua project) | The JSON-RPC + LSP protocol shell the language server is built on | MIT |
| Avalonia UI | Avalonia team | The cross-platform .NET UI framework | MIT |
| AvaloniaEdit | Avalonia community | The code editor control (port of ICSharpCode.AvalonEdit) | MIT |
| Classic.Avalonia | Avalonia community | Win98/Classic theme for VB6-style chrome | MIT |
| Dock | Wiesław Šoltés | Dockable tool-window layout | MIT |
| Pure.DI | Nikolay Pianikov | Source-generated DI (AOT-safe) | MIT |
Much of HexIDE was built in pair-programming with Claude (Anthropic).
"Visual Basic", "VB", and "VBA" are trademarks of Microsoft Corporation. HexIDE is an independent, community-built project — not affiliated with, endorsed by, or sponsored by Microsoft — and uses these names only descriptively to indicate VB6 file-format and workflow compatibility. See THIRD-PARTY-NOTICES.md for bundled-component attributions.
twinBASIC and RDCore are independent projects, each belonging to its own authors. HexIDE names them only to describe how it works with them, and is not affiliated with, endorsed by, or sponsored by either.
HexIDE is MIT-licensed throughout — both the IDE/ and LspServer/ halves. See LICENSE
and THIRD-PARTY-NOTICES.md.
The language server runs as a separate subprocess for crash isolation and a replaceable backend — not for any licensing reason.
HexIDE is in early development and contributions are welcome — bug reports, feature ideas, or pull requests. See CONTRIBUTING.md to get started. If you still work in VB6 or VBA and want to help bring the classic IDE to modern platforms, please get in touch.
