RunMat Runtime 0.5.0 is now available in the CLI, via Crates.io, and via RunMat Desktop.
If you have been watching RunMat and waiting for it to handle more of the MATLAB language surface, this is the release where a lot of that missing shape lands.
0.5.0 adds:
- folder-backed projects with
runmat.tomlandrunmat.json - named entrypoints runnable through
runmat run <name> - source-root, package-folder, class-folder, private-helper, and local dependency discovery
- requested-output-aware calls, including
nargin,nargout,varargin, andvarargout - local functions, nested functions, anonymous functions, captures, function handles, and
feval - source
classdefobject construction and runtime class metadata for constructors, properties, methods, inheritance, access rules, value vs handle behavior, static members, super calls, and custom indexing hooks - explicit indexing context for reads, writes, deletes, cell expansion,
end, and object dispatch - workspace behavior for script exports, function locals,
ans, and dynamic workspace operations through VM workspace context - typed builtin descriptors for signatures, output behavior, completions, docs, and stable errors
- structured execution outcomes for REPLs, notebooks, Desktop, WebAssembly, the LSP, and embedded hosts
- better semantic inputs for acceleration planning and future JIT coverage
RunMat now resolves much more MATLAB meaning before bytecode is generated, and those facts feed runtime execution, the language server, bytecode generation, JIT fallback decisions, and acceleration planning.
Project-shaped code now works
RunMat 0.5.0 adds project composition
around runmat.toml and runmat.json manifests. A project can name its package, declare
source roots, list local dependencies, and expose runnable entrypoints.
[package]
name = "signal-demo"
version = "0.1.0"
runmat-version = "0.5"
[sources]
roots = ["src", "examples"]
[dependencies]
filters = { path = "deps/filters", version = "0.1.0" }
[entrypoints.main]
path = "src/main"
[entrypoints.demo]
path = "examples/demo"That manifest can sit next to a normal MATLAB-style source tree:
signal-demo/
runmat.toml
src/
main.m
@SignalModel/
SignalModel.m
private/
normalizeSamples.m
examples/
demo.m
deps/
filters/
runmat.toml
src/
+filters/
lowpass.mNote: a runmat.toml file is optional for direct file execution. Without a manifest,
RunMat can still execute a file and discover supported nearby companion sources. The
manifest makes source roots, dependencies, imports, and named entrypoints explicit and
reproducible.
The MATLAB parts remain MATLAB parts. @SignalModel is still a class folder. +filters
is still a package folder. private/normalizeSamples.m is still private to its source
area. main.m can still be an ordinary script or function file.
What runmat.toml adds is a stable project boundary. [sources] tells RunMat which
folders belong to the project source index. [dependencies] makes the local filters
project available to name resolution. Named entrypoints give users, tools, and hosts a
stable way to run workflows:
cd signal-demo
runmat run main
runmat run demoDirect file execution still works. You can still run a single .m file by path. The
difference is that a manifest lets RunMat know the intended source roots, dependency
projects, and runnable entrypoints up front.
Source-level import keeps its MATLAB role. The dependency declaration makes the
filters project available; import controls which names are visible and convenient
inside a file:
import filters.*
model = SignalModel(samples);
[filtered, stats] = lowpass(model.samples, 30);
model.history{end + 1} = stats;
plot(filtered);In that example, SignalModel can resolve against the class under src, and lowpass
can resolve through the declared filters dependency. The same project graph is visible
to runtime execution, the language server, bytecode generation, JIT fallback decisions,
and acceleration planning.
The compiler now resolves MATLAB semantics first
The compiler pipeline now looks like this:
source
-> AST
-> semantic HIR
-> MIR
-> MIR analysis
-> VM layout + bytecode
-> runtime/providersRunMat now lowers source into progressively more explicit compiler products before execution, similar to how Rust's compiler pipeline works.
That matters because MATLAB syntax is compact and context-dependent. SignalModel(x)
could be construction, function call, variable indexing, or an unresolved external. A
call with one output is not the same semantic operation as the same call with two outputs.
A(i), A(i) = v, A(i) = [], C{:}, and object indexing all have different runtime
meaning.
In earlier designs, those decisions tend to spread across the interpreter, runtime
dispatch, bytecode lowering, editor tooling, JIT, and acceleration planner. 0.5.0 gives
RunMat a shared representation for the answer.
For the compiler pipeline deep dive, see the runtime/compiler pipeline post and the compiler pipeline docs.
What is now implemented
The 0.5.0 compiler/runtime migration makes several MATLAB concepts first-class.
Function calls carry callable identity and requested output count. That output count is
observable through nargout, affects varargout, and matters for function handles,
feval, cell expansion, and multi-assignment. The VM no longer has to infer it from stack
shape or string lookup.
Functions are assembly-level semantic products. RunMat can represent named functions,
local functions, nested functions, anonymous functions, captures, recursive calls,
nargin, nargout, varargin, varargout, function handles, feval, and the supported
arguments subset. Nested functions are no longer compiled as accidental global-looking
names; they carry parent and capture relationships before VM layout assigns slots.
Source classdef now participates in the same pipeline as scripts and functions. Class
source produces runtime class metadata for names, constructors, properties, methods,
inheritance, access rules, value vs handle behavior, static members, super calls, and
custom indexing hooks. There are still metaclass edges outside 0.5.0, but class source is no
longer just a parsed shape with a struct-like fallback.
Indexing and assignment carry context. HIR records whether an index expression is a read,
assignment target, deletion target, comma-list read, or function-argument expansion. MIR
then lowers that into explicit place/value behavior before bytecode is emitted. This is
especially important for end, cell indexing, deletion, and overloaded object indexing.
Workspace-visible bindings are also explicit. Scripts can export top-level variables,
functions can keep locals inside function frames, ans can remain special, and dynamic
workspace operations can route through VM workspace context instead of bypassing the
compiler model.
Builtins, tooling, and hosts share more metadata
Builtins now carry typed descriptors for signatures, output behavior, completion policy, and stable errors. That metadata feeds runtime execution, the language server, bytecode generation, JIT fallback decisions, and acceleration planning.
The execution API is also more structured. RunMat execution can report workspace deltas, display events, stream output, diagnostics, observed workspace and environment effects, figures touched, profiling data, suspension state, and fusion-plan metadata. That matters for REPLs, notebooks, Desktop, WebAssembly, language-server workflows, and embedded hosts. They need to know what happened, not only whether a scalar was returned.
Acceleration and JIT status
0.5.0 gives acceleration better inputs, but it does not move concrete GPU residency into the
compiler. The compiler can identify semantic fusion candidates, operation kinds, effects,
and instruction windows. The runtime and provider still decide whether values are resident
on a GPU, whether an operation is supported, whether data must be gathered, and which
concrete host or provider path should run.
The WGPU provider was also split out of a monolithic implementation into clearer state, initialization, helper, trait, and operation modules. That refactor is mostly about making future provider work easier to extend as more kernels, residency policies, and diagnostics land.
The JIT path has moved forward too, but it is not complete yet. Most programs still
fall back to the interpreter today. In 0.5.0, the JIT gets a better semantic boundary to
compile through: a tagged value ABI for runtime values, with semantic function identity
and requested-output behavior preserved across host calls.
From here, broader Cranelift lowering is mostly compiler engineering and coverage work, not a new MATLAB semantics project. More JIT coverage is planned before 1.0, with the interpreter remaining the correctness fallback whenever a bytecode pattern is not compiled yet.
What this changes for future work
0.5.0 also changes how future RunMat work should be done. New language behavior should
become a semantic HIR, MIR, analysis, layout, runtime, or provider product. It should not
require the VM to guess what source pattern produced a stack shape.
That is why this release matters beyond the features listed above. More builtins, more class behavior, broader JIT coverage, richer acceleration, and better tooling now have a shared compiler/runtime foundation instead of separate lookup and dispatch paths.
Scope and remaining work
0.5.0 is a major compiler/runtime revision, and an important step forward for RunMat.
The JIT is not finished and most execution still falls back to the interpreter, so CPU heavy
bytecode patterns may still fall back to the interpreter and therefore execute slower than native code.
The supported arguments subset covers common forms, not every advanced declaration shape.
Some introspection surfaces intentionally return narrower metadata than MATLAB. Full
meta.class behavior is not implemented. Async scheduling, cancellation, blocking-pool
behavior, GPU lifetime, residency, and provider-handle work continue beyond this release.
Those are scoped limitations. RunMat now has the compiler products needed to keep moving those behaviors into the right layer as coverage expands.
Try it
For an existing RunMat user, the best way to exercise 0.5.0 is to point it at a real
folder-backed project.
Add a runmat.toml, declare the source roots, give the project one named entrypoint, and
run it:
[package]
name = "my-project"
[sources]
roots = ["src"]
[entrypoints.main]
path = "src/main"cd my-project
runmat run mainIf the project depends on another local RunMat project, add it under [dependencies] and
use normal MATLAB import syntax inside the source where that improves readability.
Related docs
- Projects and Configuration for
runmat.toml, source roots, dependencies, and entrypoints. - Command Line Interface for
runmat run, direct file execution, config flags, and runtime options. - Functions and Classes for the language semantics now represented by the compiler/runtime pipeline.
- Builtins, Execution Requests, and Editor Features for the shared metadata and host/tooling surfaces.
- Fusion Engine & Residency Management and JIT Compiler for acceleration and Turbine status.
Related posts

Introducing RunMat Desktop: a high-performance MATLAB alternative
RunMat Desktop is a local, GPU-accelerated workspace for MATLAB-syntax code: editor, plots, variables, notebooks, run history, and an agent that can inspect your project.

Inside the RunMat Runtime: a Rust-like compiler pipeline to resolve MATLAB language semantics
A technical look at RunMat's Rust-like compiler pipeline for resolving MATLAB semantics across projects, functions, classes, indexing, bytecode, tooling, acceleration, and JIT work.

Open-Source MATLAB Alternatives 2026: Speed, Compatibility & Ease of Use
Benchmarks, compatibility, and setup time for four free MATLAB alternatives. Which runs your .m files, which needs a rewrite, and which can you try in 5 seconds?
Enjoyed this post? Join the newsletter
Monthly updates on RunMat internals, development, and performance tips.
Download RunMat
Download RunMat for full performance, or use RunMat in your browser for zero setup.