goja

A pure-Go ECMAScript 5.1+ engine for embedding JavaScript execution directly inside Go applications.

Library
Go
vv0.0.0-20260903201622-f87b40ad7341
7,075stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
74/100Good
Development Activity84
Maintenance44
Community68
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
83/100Excellent
Architecture88
Code Quality87
Innovation82
Learning Curve75

Goja is an implementation of ECMAScript 5.1 (with a growing set of ES6+ features) written entirely in Go, with no cgo dependency. It compiles JavaScript source into a custom bytecode and executes it on a register-based virtual machine, giving Go programs a way to run untrusted or user-supplied scripts, plugin logic, or tools like Babel and the TypeScript compiler without shelling out to Node or linking against V8.

The library is built around a small, ergonomic API: goja.New() creates a Runtime, RunString/RunProgram executes source, and Value.Export()/Runtime.ToValue() convert between Go and JS values automatically, including structs, maps, and slices via reflection. It supports calling JS functions from Go and vice versa, catching JS exceptions as typed Go errors, interrupting long-running scripts, and passes nearly the entire tc39 test262 conformance suite for the ECMAScript features it implements.

What You Get

  • A Runtime type you instantiate per-goroutine (goja.New()) to compile and run ECMAScript 5.1 source, with most of ES6+ still landing incrementally
  • Automatic two-way conversion between Go and JS values via ToValue()/Export()/ExportTo(), including Go structs, maps, slices, and functions
  • The ability to call JS functions from Go (AssertFunction) and native Go functions from JS, including constructors via goja.ConstructorCall
  • Typed error handling: JS exceptions surface as *goja.Exception and script timeouts as *goja.InterruptedError, both inspectable from Go
  • Sourcemap support and a FieldNameMapper interface (with built-in JSON-tag and lowercase-first mappers) for making Go types feel idiomatic from JS
  • A companion goja_nodejs project adding Node-style globals (console, require, an event loop) for scripts that expect a more Node-like environment

Common Use Cases

  • Letting end users write custom scripting/plugin logic (validation rules, workflow steps, pricing formulas) that a Go backend evaluates safely in-process
  • Running JS-based build tooling — Babel, the TypeScript compiler, or bundler plugins — from a Go CLI without invoking Node as a subprocess
  • Powering user-defined transformation or filter expressions inside a Go data pipeline or API gateway (e.g. request/response scripting, feature flag rules)
  • Embedding a JS-based extension/automation layer in desktop or server tools written in Go, where linking cgo/V8 isn’t acceptable
  • Unit-testing or simulating browser-side JS logic inside Go test suites without spinning up a headless browser

Under The Hood

Architecture Goja is organized as a classic front-end/back-end interpreter pipeline split across dedicated packages: parser/ and ast/ turn source text into an abstract syntax tree (with token/ and file/ providing lexical tokens and source-position tracking), compiler.go/compiler_expr.go/compiler_stmt.go lower that AST into a custom bytecode representation, and vm.go (a ~120KB register/stack-based virtual machine) executes the resulting Program. The Runtime type in runtime.go owns the object graph and global environment, with each ECMAScript built-in (Object, Array, Map, Proxy, TypedArrays, RegExp, Promise, etc.) implemented in its own builtin_*.go file and object variants (object_goreflect.go, object_gomap.go, object_goslice.go) bridging Go’s reflection-based types into the JS object model. Changing the bytecode instruction set or the core Value interface (value.go) would ripple through the compiler, VM, and every builtin, since all of them operate on the same instruction/value contracts.

Tech Stack Written in pure Go (module targets Go 1.25) with zero cgo dependencies, making it trivially cross-compilable. Direct dependencies are narrow and purposeful: dlclark/regexp2 backs regular-expression features Go’s native regexp package can’t express, Masterminds/semver and goccy/go-yaml support auxiliary tooling, go-sourcemap/sourcemap provides sourcemap parsing, and google/pprof plus golang.org/x/text support profiling and text encoding respectively. A small companion binary under goja/main.go wires in the sibling goja_nodejs project (console + CommonJS require) to run scripts from the command line, but the project’s primary interface is the importable goja package itself.

Code Quality Around two in five of the top-level Go files are _test.go files, and CI (.github/workflows/main.yml) runs gofmt -d, go vet, staticcheck, and go test ./... across two Go versions and both 386/amd64 architectures on every push and PR. Beyond its own unit tests, the suite checks out the official ECMA tc39 test262 conformance tests and runs the engine against them, which is an unusually rigorous correctness bar for a language implementation. Errors are modeled explicitly as typed values (*Exception, *InterruptedError) rather than swallowed, and the README documents exact panic/recover semantics for native Go functions that need to raise catchable JS exceptions.

API Design The public surface is deliberately small and consistent: create a Runtime, run source, convert values — with ToValue/Export/ExportTo covering the common Go-JS boundary cases with minimal boilerplate, and AssertFunction giving a low-level escape hatch when callers need explicit control over the JS this value. Naming mirrors the ECMAScript spec closely (constructors, prototypes, field mappers), which keeps the API predictable for anyone who already knows JS semantics, and the README backs every documented capability with a short, runnable example rather than prose alone.

Used by 5 apps in this directory

Go
72%
Other

Convoy

Developer Tools · Devops

2,862

Convoy is an open-source, cloud-native webhooks gateway that ingests events over HTTP or straight from Kafka, SQS, Google Pub/Sub, and RabbitMQ, then reliably delivers them to subscriber endpoints with signed payloads, automatic retries, circuit breaking, and JavaScript-based transformations.

View details
88
Repo Health
81
Technical
65
Dependency
Built with
Go72%
TypeScript15%
HTML12%
Updated 5 days ago
Go
95%
MIT

Formance Ledger

Invoicing Finance · Developer Tools · Databases

1,376

The programmable open source core ledger for fintech — build money-moving applications with atomic multi-posting transactions, account-based modeling, and Numscript, a built-in DSL for financial logic.

View details
89
Repo Health
8
Technical
68
Dependency
Built with
Go95%
Updated yesterday
Go
95%
Apache 2.0

Nakama

Developer Tools · Game Development

13,286

Open-source game backend server with built-in multiplayer, matchmaking, leaderboards, chat, authentication, and storage — deploy anywhere via Docker or binary.

View details
90
Repo Health
73
Technical
74
Dependency
Built with
Go95%
Updated 2 days ago
Go
69%
MIT

PocketBase

Databases · Ecommerce · Authentication

60,969

Open Source realtime backend in 1 file — embedded SQLite, auth, file storage, and admin UI as a single Go binary.

View details
90
Repo Health
87
Technical
77
Dependency
Built with
Go69%
JavaScript25%
Updated yesterday
Go
75%
AGPL 3.0

ZITADEL

Authentication

14,949

Open-source, API-first identity platform delivering multi-tenancy, Passkeys, OIDC, SAML, and SCIM without vendor lock-in.

View details
91
Repo Health
81
Technical
68
Dependency
Built with
Go75%
TypeScript12%
Updated 3 days ago

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search