Why? | Goals | Status | Getting started | VBA compatibility | Contributing
Note
Valo is experimental and not production-ready yet. APIs, syntax, runtime behavior, and compatibility details may change quickly.
Valo is a modern Basic-inspired programming language and runtime built in Rust.
The original idea behind Valo was simple: what if VBA had its own Node.js moment?
JavaScript was once mostly tied to the browser. Node.js made it possible to use JavaScript almost anywhere: servers, CLIs, automation, tooling, desktop workflows, build systems, and more.
Valo is exploring a similar direction for VBA-style programming.
It is designed as a standalone evolution path for Basic/VBA-style development: familiar enough for VBA, VB6, and Visual Basic developers, but with modern language features, a clean runtime, professional diagnostics, modules, FFI, a REPL, release packaging, and a growing standard runtime surface.
Valo supports two complementary modes:
.valo: native Valo syntax for modern Basic-style development..bas/.cls: VBA compatibility mode for migrating and running existing Basic-style modules and classes.
Valo is not Office automation. It is a standalone language/runtime that gives Basic-style programming a modern foundation outside of Excel, Access, COM, and the VBA editor.
VBA remains one of the most productive programming environments ever shipped. It is simple, readable, approachable, and deeply useful for automation and business logic.
But VBA is also trapped inside a legacy ecosystem:
- tied to Office and COM
- difficult to package and distribute
- missing modern tooling
- missing a standalone runtime
- lacking modern diagnostics and project structure
- hard to evolve without breaking decades of assumptions
Valo takes a successor-language approach.
Instead of trying to clone VBA forever, Valo provides:
- a modern native language mode
- a compatibility bridge for existing
.basand.clscode - a standalone runtime written in Rust
- a path toward modern tooling, packages, REPL workflows, FFI, and eventually compiled targets
This is similar in spirit to successor language projects:
- JavaScript → TypeScript
- Java → Kotlin
- C++ → Carbon
- VBA → Valo
Valo keeps the productivity and readability of Basic-style languages while building a runtime that can grow beyond the limitations of the original VBA environment.
The long-term goal is simple:
Take the productivity of VBA out of Office and let it run anywhere.
Valo is designed around the following goals:
- Familiar Basic-style syntax for developers coming from VBA, VB6, or VB.NET.
- First-class VBA compatibility for
.basand.clsmigration. - Modern native syntax for new
.valoprojects. - Standalone runtime independent of Office, COM, or the VBA editor.
- Professional diagnostics with explicit diagnostic codes and source spans.
- Modular project structure with imports and qualified symbols.
- Strong runtime foundations for arrays, objects, variants, errors, structures, classes, and native types.
- Experimental native interop through VBA-style
Declare,PtrSafe,LongPtr, callbacks, andAddressOf. - A practical migration path from legacy automation code to a modern runtime.
- A clean implementation architecture suitable for future tooling, bytecode, and compiled targets.
Valo is still experimental, but its direction is clear: a modern Basic-family language with compatibility as a bridge, not a cage.
Valo is currently an experimental language/runtime in active development.
It already includes a substantial interpreter, parser, semantic validator, module loader, diagnostics engine, REPL, CLI, compatibility runtime, native FFI layer, and cross-platform release packaging.
Implemented today:
.valo,.bas, and.clsfile support- exported VBA
.clscompatibility - modules and imports
- classes, properties, events, and object lifecycle
- native
Sub New/Sub Terminate - deterministic cleanup with
Sub DisposeandUsing - VBA
Class_Initialize/Class_Terminate - native
Structurevalue types with methods, properties, and constructors - VBA-compatible fields-only
Type - default properties and indexer-style access
Interface,Implements,Shared, andFriend- classic VBA function return assignment semantics
- modern
Returnsyntax - native
Iterator FunctionandYield Try / Catch / Finally- VBA
On Error,Err,Resume, andErl - advanced arrays, including multidimensional and jagged patterns
Array,Split,Join, andFilter- native and VBA-compatible type system
Variant,Object,Empty,Null- VBA-compatible implicit
Variantdefaults CallByNameDebug.PrintVBA.namespace fallback- experimental native FFI through
Declare,PtrSafe,LongPtr, andAddressOf - callbacks and native function pointers
VarPtr,StrPtr, andObjPtr- platform-aware native library loading
- structure and array write-back for supported FFI cases
- interactive REPL
- professional diagnostics
- release packaging for Linux, Windows, and macOS
- clippy-clean Rust codebase
Valo is not yet a full production compiler. There is currently no bytecode VM, package manager, LSP, formatter, or complete standard library.
Native FFI is already available experimentally through VBA-style Declare, PtrSafe, LongPtr, callbacks, AddressOf, and platform-aware native library loading.
Valo intentionally separates modern native syntax from compatibility syntax.
Native .valo files use clean, modern Basic-style syntax:
Class Counter
Private value As Integer
Public Sub New()
value = 0
End Sub
Public Sub Increment()
value = value + 1
End Sub
Public Default Property Get Item() As Integer
Return value
End Property
Public Sub Terminate()
Debug.Print "counter disposed"
End Sub
End Class
Public Structure Point
Public X As Integer
Public Y As Integer
Public Sub New(ByVal x As Integer, ByVal y As Integer)
X = x
Y = y
End Sub
Public Function Sum() As Integer
Return X + Y
End Function
End Structure
Sub WriteBytes()
Dim data() As Byte
ReDim data(0 To 15)
data(0) = CByte(255)
End Sub
Sub Main()
Dim counter As New Counter
counter.Increment()
counter.Increment()
Console.WriteLine(counter)
End SubVBA .bas and .cls files can use compatibility syntax:
VERSION 1.0 CLASS
BEGIN
MultiUse = -1
END
Attribute VB_Name = "Counter"
Option Explicit
Private value As Long
Private Sub Class_Initialize()
value = 0
End Sub
Private Sub Class_Terminate()
Debug.Print "counter disposed"
End Sub
Public Property Get Item() As Long
Attribute Item.VB_UserMemId = 0
Item = value
End PropertyThe goal is not to force modern Valo code to use legacy metadata. Instead, Valo accepts VBA metadata where needed for migration while offering cleaner syntax for new code.
Try
DangerousOperation()
Catch ex As Error
Console.WriteLine("Error " & ex.Number & ": " & ex.Message)
Finally
Console.WriteLine("cleanup")
End TrySub Main()
On Error GoTo Handler
Err.Raise 1001, "Example", "Something failed"
Exit Sub
Handler:
Debug.Print Err.Number
Debug.Print Err.Description
Resume Next
End SubFunction Add(ByVal a As Long, ByVal b As Long) As Long
Add = a + b
End Function
Function AddModern(ByVal a As Long, ByVal b As Long) As Long
Return a + b
End FunctionObject returns support classic Set semantics:
Function CreateUser() As User
Dim u As New User("Valo")
Set CreateUser = u
End FunctionImport Math
Import Models As M
Sub Main()
Console.WriteLine(Math.Add(10, 20))
Dim user As New M.User("Valo")
Console.WriteLine(user.Name)
End SubInterface IUpdatable
Sub Update()
End Interface
Class Player Implements IUpdatable
Friend Shared Count As Long
Public Sub Update() Implements IUpdatable.Update
Count = Count + 1
Debug.Print "Updating player"
End Sub
End Class
Sub Main()
Dim p As New Player
p.Update()
Debug.Print Player.Count
End SubStructure Vec2
X As Double
Y As Double
Public Sub New(ByVal x As Double, ByVal y As Double)
X = x
Y = y
End Sub
Public Function LengthSquared() As Double
Return (X * X) + (Y * Y)
End Function
End Structure
Sub Main()
Dim v As New Vec2(3#, 4#)
Debug.Print v.LengthSquared()
End SubSub Main()
Dim matrix(1 To 3, 1 To 2) As Integer
matrix(1, 1) = 42
matrix(3, 2) = 99
Console.WriteLine(matrix(1, 1))
Console.WriteLine(matrix(3, 2))
End SubSub Main()
Dim parts As Variant
parts = Split("A,B,C", ",")
Console.WriteLine(parts(0))
Console.WriteLine(Join(parts, "-"))
Console.WriteLine(VBA.Join(parts, "/"))
End SubSub Main()
Dim b As Byte
Dim i As Integer
Dim l As Long
Dim x As Int64
Dim u As UInt64
Dim d As Double
Dim when As Date
b = CByte(255)
x = 9223372036854775807
u = 18446744073709551615
Console.WriteLine(TypeName(x))
Console.WriteLine(VarType(d))
End SubValo can call native libraries through VBA-style Declare.
Declare PtrSafe Function puts Lib "libc" CDecl (
ByVal value As String
) As Long
Declare PtrSafe Function strlen Lib "libc" CDecl (
ByVal value As String
) As Long
Private Sub Main()
puts("Hello from native Valo FFI!")
Debug.Print strlen("Valo")
End SubOn Windows, Valo can call Win32 APIs:
Declare PtrSafe Function MessageBoxA Lib "user32" Alias "MessageBoxA" StdCall (
ByVal hwnd As LongPtr,
ByVal text As String,
ByVal caption As String,
ByVal flags As Long
) As Long
Private Sub Main()
MessageBoxA(0, "Hello from Valo", "Valo Win32", 0)
End SubFFI is experimental. Complex COM/OLE interop, full BSTR/SAFEARRAY ownership semantics, mutable string buffers, and Office automation are not currently implemented.
| Extension | Mode | Purpose |
|---|---|---|
.valo |
Native Valo | Modern Basic-inspired development |
.bas |
VBA module compatibility | Legacy standard modules |
.cls |
VBA class compatibility | Exported class modules |
Valo ships with a command-line interface for running, checking, and experimenting with code.
valo run examples/hello.valo
valo check examples/types_showcase.valo
valo repl
valo version
valo helpvalo run examples/hello.valovalo check examples/modules/main.valovalo replThe REPL currently supports interactive experimentation. Some declaration-heavy workflows are still evolving.
valo> Dim x As Integer
valo> x = 10
valo> Console.WriteLine(x)
10Valo is currently experimental, but prebuilt releases are available for supported platforms.
On Linux and macOS:
curl -fsSL https://raw.githubusercontent.com/valolang/valo/main/scripts/install.sh | bashAfter installation, add Valo to your PATH if the installer asks you to:
export PATH="$HOME/.valo/bin:$PATH"Then verify:
valo version
valo helpVALO_VERSION="v0.1.0-2026.05.21" curl -fsSL https://raw.githubusercontent.com/valolang/valo/main/scripts/install.sh | bashYou can also download prebuilt binaries from the releases page:
https://github.com/valolang/valo/releasesAvailable release assets may include:
| Platform | Asset |
|---|---|
| Linux x64 | valo-linux-x64.tar.gz |
| Linux x86 | valo-linux-x86.tar.gz |
| macOS ARM64 | valo-macos-arm64.tar.gz |
| macOS x64 | valo-macos-x64.tar.gz |
| Windows x64 | valo-windows-x64.zip |
| Windows x86 | valo-windows-x86.zip |
Windows users can download the .zip, extract it, and run:
.\valo.exe version
.\valo.exe run examples\hello.valoYou can also build Valo from source.
You need Rust installed.
git clone https://github.com/valolang/valo
cd valo
cargo build --releaseRun the CLI:
./target/release/valo version
./target/release/valo run examples/hello.valoOn Windows:
.\target\release\valo.exe version
.\target\release\valo.exe run examples\hello.valoRun the full test suite:
cargo testRun quality checks:
cargo fmt
cargo clippy --all-targets -- -D warnings
cargo build --releaseCreate hello.valo:
Sub Main()
Console.WriteLine("Hello, Valo")
End SubRun it:
valo run hello.valoOutput:
Hello, ValoValo includes professional, Rust-inspired diagnostics with explicit diagnostic codes and source spans.
Example:
error[V1100]: Cannot assign String value to Integer variable
--> examples/demo.valo:4:9
|
4 | age = "twenty"
| ^^^^^^^^^ expected Integer
|
= help: use an explicit conversion if the value is intendedDiagnostics are designed to be actionable, stable, and suitable for future editor tooling.
Valo is implemented in Rust and organized around a clean language pipeline:
source
↓
preprocessor
↓
lexer
↓
parser
↓
AST
↓
semantic validation
↓
module loader
↓
tree-walking interpreter
↓
runtime values, builtins, and FFIMajor components include:
frontend: source processing, lexer, parser, AST, semantic validation, module loadingruntime: values, diagnostics, spans, type names, coercion, numeric operations, comparisonsbackend: execution backendsbackend/interpreter: current tree-walking interpreterbuiltins: modular runtime builtinscli: command-line interface and REPL
The interpreter is currently AST-based. A bytecode VM is a future direction, not the current execution model.
Valo supports a growing set of VBA-compatible features:
.basand.clsparsing- exported
.clsenvelopes Attribute VB_NameAttribute VB_UserMemId = 0Class_InitializeClass_TerminateType / End TypeOn ErrorErrResumeErlDebug.PrintCallByNameDeclare,PtrSafe,LongPtr,LongLongAddressOfVarPtr,StrPtr,ObjPtrVBA.Join,VBA.Split,VBA.TypeName, and other namespace fallbacksVariant,Object,Empty,Null- implicit
Variantdefaults - classic function return assignment
Array,Split,Join,FilterLBound,UBound,ReDim,EraseVarType,TypeName,IsObject,IsArray,IsEmpty,IsNull
Compatibility is pragmatic and growing. Valo is not a COM runtime and does not currently implement Office automation, IDispatch, or full COM interop.
Experimental native FFI is supported through VBA-style Declare, PtrSafe, LongPtr, AddressOf, callbacks, and platform-aware library loading. Complex COM/OLE interop, full BSTR/SAFEARRAY ownership semantics, and Office automation are still outside the current scope.
The research/ directory contains real-world VBA/VB-style modules, parser edge cases, runtime stress tests, FFI demos, interoperability experiments, and prototypes used during Valo development.
These files are used to:
- validate VBA compatibility
- reproduce parser/runtime bugs
- stress the interpreter and FFI layer
- benchmark performance
- explore future language features
- prototype APIs and module-system behavior
Files in this directory are experimental and may change frequently as the language evolves.
Valo is still experimental.
Not implemented yet:
- package manager
- bytecode VM
- LSP
- formatter
- full standard library
- filesystem APIs
- full Date/Time API
- COM interop
- Office automation
- inheritance
- generics
- full Collection / Dictionary runtime
- async runtime
- complete REPL declaration workflow
Some compatibility areas are intentionally pragmatic today:
CurrencyandDecimalmay use simplified mixed arithmetic paths.Rnddoes not yet perfectly replicate every VBA edge case..clsmetadata is parsed for compatibility, but COM semantics are not implemented.- FFI intentionally rejects unsafe ownership cases such as mutable string buffers, complex COM/OLE Variant pointers, and nested non-blittable structure layouts.
Near-term priorities:
- Collection and Dictionary runtime types
- Date and Time standard library
- FileSystem APIs
- richer string/runtime builtins
- compatibility-driven stabilization using real VBA modules
- syntax highlighting
- improved release packaging
- stronger REPL workflows
- import-system refinement
Medium-term priorities:
- formatter
- LSP
- package manifest
- project-level module configuration
- benchmark suite
- standard library organization
- bytecode IR exploration
- field/member dispatch optimization
Long-term directions:
- bytecode VM
- deeper FFI stabilization
- embedding API
- WASM/native backend groundwork
- editor integrations
- migration tooling for VBA projects
Start here:
- Getting started
- Language syntax
- Expressions
- Classes and objects
- Modules and imports
- Error handling
- Types
- VBA compatibility
- FFI
- REPL
- Examples
Architecture docs:
Valo is in active development.
Good areas to contribute:
- language tests
- VBA compatibility cases
- documentation
- examples
- diagnostics
- standard library design
- CLI and REPL improvements
- runtime builtins
- import-system design
- real-world
.bas/.clscompatibility cases
Before submitting changes, run:
cargo fmt
cargo clippy --all-targets -- -D warnings
cargo test
cargo build --releaseSee CONTRIBUTING.md for more information.
Valo is licensed under the MIT License.

