Enso Analytics is a visual/textual programming environment for data preparation and analysis. This repository contains two top-level products that share this monorepo:
- Enso Engine — the Enso language implementation: parser, compiler, interpreter (Truffle/GraalVM), language server, and the Enso standard library. Written in Scala, Java, and Rust.
- Enso IDE — a desktop application (Electron) with a visual graph editor and a dashboard for project/cloud management. Written in TypeScript; Vue is the main UI framework. The Dashboard feature is still in React as a historical artifact and is being progressively migrated to Vue.
The two products are glued together by several generated/shared artifacts: the
Rust parser is compiled to both WASM (for the GUI) and a JNI cdylib (for
the JVM), and its AST types are code-generated into Java so the engine can
deserialize parser output.
app/— Desktop app (Electron), GUI (Vue; the Dashboard feature is still React while it's being ported), ydoc server, markdown/table CodeMirror grammars, Rust→WASM bindings. pnpm monorepo.engine/— The Enso language engine. Mixed Scala/Java undersbt. Runtime uses GraalVM Truffle.lib/rust/— Rust workspace libraries (parser, prelude, reflect/metamodel, zst). Some crates ship to crates.io.lib/java/— JPMS-friendly wrappers around third-party Java libraries, plus interpreter DSL, persistance, and ydoc server.lib/scala/— Scala support libraries (pkg, project-manager, editions, logging, etc.).build_tools/— The./runCLI (Rust). Historically the canonical build orchestrator; now legacy and being replaced by Bazel. Still in active use for many flows.distribution/— Packaged output layout, templates, and the Enso standard library sources underdistribution/lib/Standard/.std-bits/— Java helpers that the Enso standard library calls via host interop.test/— Enso-language test projects (one per standard library module).tools/— Auxiliary dev tools (IGV plugin, http test helper, CI scripts, benchmark analysis).docs/— Extensive developer documentation (RFCs, style guides, runtime internals, LSP protocol). Start atdocs/README.md.project/— SBT plugins and build helpers for the engine.internal/,bazel_scripts/,toolchains/,nix/,patches/— Build plumbing.
Four coexist; which one to use depends on what you're building:
- Cargo — for everything under the
[workspace]in rootCargo.toml(build_tools + lib/rust + app/rust-ffi). - pnpm + Vite/esbuild — for the TypeScript monorepo (packages listed in
pnpm-workspace.yaml). - SBT — for the Scala/Java engine (
build.sbt). Seedocs/sbt-cheatsheet.md. - Bazel — the target build system. Actively being rolled out across the
repo;
BUILD.bazelfiles live alongsideCargo.toml/package.json. Prefer Bazel targets for new build functionality, and migrate existing flows to Bazel when you touch them.
The ./run (or run.cmd / run.ps1) script at the repo root dispatches to the
Enso build CLI (in build_tools/cli/) — the legacy end-to-end orchestrator.
It still works (and transparently calls Bazel when available, Cargo otherwise),
but the plan is to replace it with Bazel targets. Don't extend ./run with new
functionality unless Bazel can't cover the case yet.
- Rust: stable channel pinned in
rust-toolchain.toml(currently 1.90.0) withwasm32-unknown-unknowntarget. WorkspaceCargo.tomlpins dependency versions — members reference them with{ workspace = true }.rustfmt.tomlandclippy.tomlare repo-wide; follow them. - Scala/Java: GraalVM-based. See
docs/infrastructure/forsbt, native-image, dual-JVM, and GraalVM upgrade guides. - TypeScript: TS
catalog:version inpnpm-workspace.yaml. Usecorepack pnpm(not barepnpm/npm).
- Root
CHANGELOG.mdis user-facing and PR-linked — add an entry when shipping a user-visible change. - Licensing is split: Engine = Apache-2.0, IDE = AGPL-3.0 (see
app/gui/LICENSE). - The Rust workspace follows
docs/style-guide/rust.md; additional house rules live in~/.claude/skills/rust-guidelines(load it before Rust edits). - When a module, crate, or package lacks a CLAUDE.md, create one when you start
working in it — see
~/.claude/skills/project-structure.
- The Rust parser is the source of truth for the AST. Changing it means
regenerating Java bindings (
lib/rust/parser/generate-java/) and re-bundling WASM (app/rust-ffi/). The engine and IDE both consume it. - "Polyglot" has multiple meanings here: (1) GraalVM polyglot — Enso calling
JS/Python/Java at runtime; (2) Enso Polyglot Bridge (EPB) — an internal
sub-language for single-threaded language contexts; (3)
ydoc-server-polyglot— the ydoc server bundled to run inside the GraalVM/JVM process. Don't conflate them. - The "standard library" has two halves: pure Enso sources in
distribution/lib/Standard/and Java helpers instd-bits/. Adding a new stdlib primitive usually touches both.