bento

module
v0.0.0-...-e0cb5ea Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 9, 2026 License: MIT

README

bento

ci Release Go Reference Go Report Card License

bento is a TypeScript runtime built in Go, a Bun alternative. It runs your existing Node.js and Bun code unchanged, compiles the typed parts of your TypeScript to Go for speed, and lets you reach into any Go library straight from TypeScript. The whole thing is pure Go with zero cgo, so it ships as one static binary that cross-compiles to every platform.

The JS engine is modernc.org/quickjs, a pure-Go ES2023 engine, so there is no V8 to build and nothing native to link. That is what keeps bento a single file you can drop onto any machine and run.

Full docs and guides live at bento.tamnd.com.

Install

go install github.com/tamnd/bento/cmd/bento@latest

Prefer a prebuilt binary? Grab an archive, a .deb/.rpm/.apk, or a checksum from releases. A Homebrew tap and a Scoop bucket ship with each release once they are wired up:

# Homebrew (macOS)
brew install tamnd/tap/bento

# Scoop (Windows)
scoop bucket add tamnd https://github.com/tamnd/scoop-bucket
scoop install bento

Quick start

Write a TypeScript file and run it:

// app.ts
const name = "world";
console.log(`hello, ${name}`);
bento run app.ts

Reach into a Go library from TypeScript with a go: import. You get the speed and the ecosystem of Go without leaving your script:

import { Sum } from "go:github.com/tamnd/bento/examples/mathx";

console.log(Sum([1, 2, 3, 4])); // 10

Why bento

Drop-in compatibility. Your Node.js and Bun code runs as is, so you are not rewriting anything to try it.

Any Go library from TypeScript. A go: import gives you the whole Go module ecosystem from a .ts file, with types carried across the boundary.

Speed where it counts. The typed parts of your TypeScript compile down to Go, so the hot paths run as compiled code instead of interpreted script.

One static binary, zero cgo. The runtime and its JS engine are pure Go, so bento cross-compiles to every GOOS and GOARCH and installs as a single file with nothing to link and nothing to download at runtime.

Status

bento is early. The runtime, the CLI, and the go: import bridge are under active development, and not every Node or Bun API is in place yet. Track what runs today at bento.tamnd.com and in the releases. If something you rely on is missing, open an issue.

License

MIT. See LICENSE.

Directories

Path Synopsis
cmd
bento command
Command bento is a TypeScript runtime built in Go.
Command bento is a TypeScript runtime built in Go.
pkg
build
Package build is bento's ahead-of-time path: it type-checks an entry module with the real frontend, lowers it to a Go program, and compiles that program to a native binary with the Go toolchain.
Package build is bento's ahead-of-time path: it type-checks an entry module with the real frontend, lowers it to a Go program, and compiles that program to a native binary with the Go toolchain.
cli
Package cli is bento's command surface: the cobra tree, the global flags, and the fang-rendered help and errors.
Package cli is bento's command surface: the cobra tree, the global flags, and the fang-rendered help and errors.
engine
Package engine defines the JavaScript engine service provider interface that the rest of bento runs on top of.
Package engine defines the JavaScript engine service provider interface that the rest of bento runs on top of.
engine/quickjs
Package quickjs is the default bento JavaScript engine backend.
Package quickjs is the default bento JavaScript engine backend.
frontend
Package frontend turns TypeScript and modern JavaScript source into the JavaScript dialect the engine executes.
Package frontend turns TypeScript and modern JavaScript source into the JavaScript dialect the engine executes.
frontend/adapter
Package adapter is the only bento package that is allowed to import microsoft/typescript-go.
Package adapter is the only bento package that is allowed to import microsoft/typescript-go.
goimport
Package goimport owns bento's Go interoperability: it turns a go: import specifier into a Go import path plus an optional module version, and it is the home of the .d.ts generation and the value marshaling that let a TypeScript program call a pure-Go library as a direct Go call (Spec 2075, document 16).
Package goimport owns bento's Go interoperability: it turns a go: import specifier into a Go import path plus an optional module version, and it is the home of the .d.ts generation and the value marshaling that let a TypeScript program call a pure-Go library as a direct Go call (Spec 2075, document 16).
goimport/anyfixture
Package anyfixture is a go: import fixture for the section 6.12 any crossing.
Package anyfixture is a go: import fixture for the section 6.12 any crossing.
goimport/bridge
Package bridge is the runtime helper package a go: import's emitted code calls to marshal values across the interop boundary (16_go_interop.md section 9.4).
Package bridge is the runtime helper package a go: import's emitted code calls to marshal values across the interop boundary (16_go_interop.md section 9.4).
goimport/cgodepfixture
Package cgodepfixture is a cgo-detection fixture for document 16 section 9.5.
Package cgodepfixture is a cgo-detection fixture for document 16 section 9.5.
goimport/funcfixture
Package funcfixture is a go: import fixture for the section 6.9 and 7.6 callback crossing.
Package funcfixture is a go: import fixture for the section 6.9 and 7.6 callback crossing.
goimport/mapfixture
Package mapfixture is a go: import fixture for the section 6.5 map crossing.
Package mapfixture is a go: import fixture for the section 6.5 map crossing.
goimport/optfixture
Package optfixture is a go: import fixture for the section 6.13 opaque handle crossing.
Package optfixture is a go: import fixture for the section 6.13 opaque handle crossing.
goimport/structfixture
Package structfixture is a tiny Go package the go: struct-crossing tests import.
Package structfixture is a tiny Go package the go: struct-crossing tests import.
loop
Package loop is bento's event loop.
Package loop is bento's event loop.
lower
Package lower is bento's ahead-of-time type lowering: it turns the resolved, flow-narrowed types the frontend hands it (pkg/frontend) into the Go source the Go toolchain then compiles.
Package lower is bento's ahead-of-time type lowering: it turns the resolved, flow-narrowed types the frontend hands it (pkg/frontend) into the Go source the Go toolchain then compiles.
lower/conformance
Package conformance is the fixture corpus for the ahead-of-time lowerer.
Package conformance is the fixture corpus for the ahead-of-time lowerer.
node
Package node implements bento's Node.js core module layer.
Package node implements bento's Node.js core module layer.
partition
Package partition is bento's partitioner: it reads a fully checked TypeScript program through the frontend and decides, for every function and module, whether it runs as ahead-of-time compiled Go, as interpreted engine code, or as speculatively compiled code guarded at runtime.
Package partition is bento's partitioner: it reads a fully checked TypeScript program through the frontend and decides, for every function and module, whether it runs as ahead-of-time compiled Go, as interpreted engine code, or as speculatively compiled code guarded at runtime.
resolve
Package resolve turns an import specifier into a concrete module on disk.
Package resolve turns an import specifier into a concrete module on disk.
runtime
Package runtime wires an engine and an event loop into a working JavaScript host and runs a program.
Package runtime wires an engine and an event loop into a working JavaScript host and runs a program.
value
Package value is bento's shared value model: the Go types that represent JavaScript values on both the compiled (typed) and interpreted (dynamic) sides, so a value computed by lowered Go and a value computed by the engine are the same object.
Package value is bento's shared value model: the Go types that represent JavaScript values on both the compiled (typed) and interpreted (dynamic) sides, so a value computed by lowered Go and a value computed by the engine are the same object.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL