LICENSE=BSD-3-ClauseCGO_ENABLED=0go-embedded-julia is in development, and its parser and its lowering are released: v0.3.0 completes milestones M0 (the oracle harness, against julia 1.12.6), M1 (a Go port of JuliaSyntax), identical to julia's Meta.parseall on 1191 of 1191 files of julia's own tree, and M2 (lowering: a port of julia 1.12.6's femtolisp front end), identical to Meta.lower on 53 997 of 53 997 forms of that tree. Milestone M3 (the Core runtime) is in progress: v0.9.0 extends the package interp, a port of julia 1.12.6's src/interpreter.c that runs lowered code over Core, to struct and abstract type definitions, with parameters, with julia's default constructors and to methods with where clauses, dispatched with static parameters (85 Core-only programs show the same value as julia; Base is not there yet), on top of Julia's type objects, subtyping and method specificity, identical to julia on 20 000 random pairs, and the dispatch of concrete calls, identical to julia's which on 9 000 calls. It will be a pure-Go, embeddable Julia interpreter: julia's parser and lowering ported to Go, and an interpreter over the lowered IR that runs Julia's Base unchanged, for the julia cells of go-notebook and its WebAssembly playground.
release v0.9.0 (2026-10-31) done M0 oracle harness (julia 1.12.6) done M1 parser: 1191/1191 files done M2 lowering: 53997/53997 forms now M3 Core: types, dispatch, interp next M3 boot.jl, builtins, intrinsics goal julia cells in go-notebook scope an interpreter, not a JIT plan github.com/go-scikit/roadmap
Julia's front end becomes Go, Base stays Julia, and the boundary between them is mapped onto libraries the fleet already has. This is the plan of the roadmap's bibliography, not a result.
JuliaSyntax (the parser, 11 326 lines of Julia) and the femtolisp lowering julia 1.12.6 ships (julia-syntax.scm, macroexpand.scm, ast.scm, match.scm) ported to Go. Until Base is loaded no Julia can run, so the front end has to be native: a Go VM has no femtolisp.
The whole instruction set an interpreter must execute is 12 node types and 30 Expr heads. Julia's own C interpreter over it, src/interpreter.c, is 1 118 lines.
Base (140 705 lines of Julia) is run as is through the interpreter, at build time, and the resulting heap is shipped as an image. Nothing of Base is rewritten natively, so a Base fix upstream is not ported twice.
Intrinsics, ccall targets and the runtime itself map onto Go: math/big and go-bignum for GMP and MPFR, go-ndarray for BLAS and LAPACK, the regexp stack of go-ruby-regexp for PCRE2, go-fft for FFTs.
The julia cells of go-notebook and of its WebAssembly playground, the way rbgo, the Ruby VM of go-embedded-ruby, backs its ruby cells.
Julia is MIT, and its front end, runtime and Base may be translated to Go with the notice kept. The GPL parts of SuiteSparse are avoided, and GMP and MPFR (LGPL) are neither linked nor translated.
Effort is on the plan's scale: S is days, M weeks, L months, XL several months. M3 and M4 dominate. The differential oracles of the front end are built first, because they are stronger than Julia's test suite there.
Done: merged as pull request 1 of go-embedded-julia/julia, against julia 1.12.6. A Go tool that runs the reference julia (a pinned release) on a corpus and stores its outputs: parse trees, Meta.lower, Test summaries, printed values. Exit test: the outputs are checked in as golden files, regenerated by one command.
Done: released as v0.2.0 (2026-10-26), a Go port of JuliaSyntax 29ec5226f7b1 (the version julia 1.12.6 ships). syntax.ParseAll returns the same Expr as Meta.parseall: tokens, green trees and Expr identical on 1191 of 1191 files of julia 1.12.6's share/julia tree (base, Compiler, stdlib, test; 18.5 MB) and on 976 of 976 golden snippets. One core: 0.98 s against 1.39 s for julia (0.70x). Bounded (64 MiB, depth 4000) and fuzzed. Known gap: on a few malformed inputs JuliaSyntax itself throws and julia falls back to flisp, which is not ported.
Done: released as v0.3.0 (2026-10-28). The lower package ports julia 1.12.6's femtolisp front end (julia-syntax.scm, macroexpand.scm, ast.scm, match.scm): lower.NewState().Lower(ex) is Meta.lower of a macro-expanded top-level form, compared field by field modulo gensym numbering. Identical on 53 997 of 53 997 forms of julia's share/julia tree (base, Compiler, stdlib, test; 1191 of 1191 files), 124 of 124 lowering snippets, 48 of 48 hygienic-scope forms and 477 of 477 built expressions (error paths, rare heads); deparse 119 of 119 and front-end functions 151 of 151 against julia --lisp. 100% statement coverage. Lower refuses trees deeper than lower.MaxDepth (1000) and FuzzLower runs on every pull request. Known gap: a Float64 inside a lowering error message returns lower.ErrUnsupported.
In progress. Types, subtyping, method tables, dispatch, the builtins (63 in julia 1.12.6), the intrinsics (93 in julia 1.12.6), the interpreter and boot.jl. Released so far: core (v0.3.0, v0.4.0) — Julia's type objects, apply_type, and subtyping (a port of jltypes.c and subtype.c of 1.12.6, without intersection): identical to julia on 20 000 random pairs and 4 902 cases from test/subtype.jl; and method specificity (jl_type_morespecific), identical to Base.morespecific on the same corpus. core/dispatch (v0.5.0): method tables with world ages and the dispatch of concrete calls, identical to julia's which and dispatch environment on 9 000 calls over 1 500 random method tables (4 675 method choices, 87 ambiguities). interp (v0.6.0 to v0.9.0): a port of julia 1.12.6's interpreter.c that runs lowered code over Core, with 24 builtins and the integer and float intrinsics; v0.7.0 runs struct and abstract type definitions with julia's default constructors (jl_ctor_def) and user-defined outer constructors, and calling a type dispatches on its constructors; v0.8.0 dispatches methods with where clauses with static parameters (e.g. f(x::T) where {T<:Integer} = T), through the TypeVar and UnionAll constructors of boot.jl:335-338, built in Go until boot.jl runs; v0.9.0 runs structs and abstract types with parameters (struct Q{T}, abstract type A{T}): Q(1) infers Q{Int64}, Q{Integer}(1) runs the inner constructor, a parameter no field constrains gets no outer constructor (as jl_ctor_def decides), and a type argument dispatches as Type{X}; 85 Core-only programs show the same value in Go and julia 1.12.6, 100% statement coverage, fuzzed. Not yet: type intersection (and with it the interference sets julia 1.12 uses to order matches), Base (and constructor arguments that need convert), macro expansion, redefining a struct that has parameters (it needs Base.getproperty), const and atomic fields, arrays, finally, the remaining builtins and intrinsics; interpreter speed against julia is not measured, and subtyping is 1.49× slower than jl_subtype on one core (open defect). Exit test: test/subtype.jl, specificity.jl, intrinsics.jl and the parts of core.jl that need no Base I/O.
Base_compiler.jl and Base.jl evaluated; the jl_*, libc and libuv shim (about 524 + 88 + 78 call sites); the Compiler interpreted for _return_type; an image writer and reader. Exit test: Base loads, and a list of test/ files passes.
GMP and MPFR on math/big and go-bignum, a PCRE2 front end on go-ruby-regexp, utf8proc tables, a dSFMT port, Printf, Dates, Random, Statistics and LinearAlgebra on go-ndarray. Exit test: the gmp, mpfr, regex, unicode, rational and complex tests, and the standard-library tests, with seeded Random streams byte-identical.
The Julia to Go value table, the names a cell defines and uses, errors and worker limits, and the go-scikit bindings. Exit test: a mixed Go and Julia example notebook transcript in the go-notebook docs.
A lazily loaded Julia core, image loading, and SVG display through the existing sanitizer. Exit test: a first result in less time than the Ruby core on the same machine, with the size recorded.
Every number below was counted by a Go program over the Julia sources the plan names, not estimated.
The bibliography counted 94 (81 ADD_I, 12 ALIAS and 1 hidden) on julia 1.15-DEV sources; julia 1.12.6, the release the port follows, has 93. All but llvmcall and the pointer group map to Go in a few lines each, on math/bits and math.
The bibliography counted 83 on julia 1.15-DEV sources; julia 1.12.6 has 63. From src/builtin_proto.h: getfield, setfield!, isa, ===, apply_type, invoke and the rest, each one a Go function.
856 ccall and 40 @ccall in 202 files. By target: 524 on the Julia runtime and ios_*, 88 on libc, 81 on MPFR (and 29 more generated by loops), 78 on libuv, 40 on GMP, 18 on PCRE2, 15 on utf8proc.
Base's elementary functions are written in Julia over intrinsics, so they are bit-identical by construction, and Base has no llvmcall( site.
182 call BLAS and LAPACK. They are implemented as Go functions over go-ndarray's linalg on the column-major buffer a Julia matrix owns, without copying. Missing kernels are added to go-ndarray, not to the VM.
Neither Base nor the standard library has one: an FFTW.jl-style API over go-fft is a separate package, not part of the VM.
It keeps Julia's semantics, not its native speed. An interpreter cannot match Julia's JIT on loops, so heavy computation goes through the Go libraries (go-ndarray, go-bignum, go-fft). The comparisons that can hold are start-up and first result, and the kernels routed to those libraries. The plan lists every interpreter speed statement as unverified, except the parser's: on one core, parsing julia 1.12.6's share/julia tree takes 0.98 s against 1.39 s for Meta.parseall (0.70x). No speed is claimed for the lowering.
The organization holds the interpreter's repository, julia, and its landing, documentation and brand.
The interpreter. Its M0, the oracle harness against julia 1.12.6, and M1, a Go port of JuliaSyntax identical to Meta.parseall on 1191/1191 files of julia's tree, are released as v0.2.0 (2026-10-26). M2, lowering, a Go port of julia 1.12.6's femtolisp front end identical to Meta.lower on 53 997 of 53 997 forms of julia's tree (1191/1191 files), is released as v0.3.0 (2026-10-28). M3, the Core runtime, is in progress: the core package (v0.3.0, v0.4.0) holds Julia's type objects, apply_type, subtyping and method specificity, core/dispatch (v0.5.0, 2026-10-30) the method tables and the dispatch of concrete calls, and interp (v0.6.0 to v0.9.0, 2026-10-31) an interpreter of lowered code over Core that runs struct and abstract type definitions, with parameters, with julia's default constructors and methods with where clauses.
The documentation (Hugo + Hextra): the plan and its milestones, the architecture, the runtime boundary with its counts, and the licences. Source →
Logos and icons for the organization, in SVG / PNG / JPG / ICO / ICNS across colour, white and black variants. The mark is Julia's subtype operator, <:.