Skip to content

Repository files navigation

polyglot-playground

Sixteen language toolchains, each a small declarative Flox environment — plus a polyglot environment that composes all sixteen into one. Clone and activate locally, or pull the same environments from FloxHub.

C/C++ · Rust · Go · Zig · Node/TypeScript · Python · Ruby · PHP · Perl · Lua · Erlang/Elixir · Haskell · Kotlin · Clojure · Scala · R/Julia

Quick start

# the whole 16-language stack, from this repo
git clone <repo-url> && cd polyglot-playground/polyglot
flox activate

# just one toolchain
cd ../rust-dev && flox activate

# …or straight from FloxHub, no clone needed
flox activate -r flox-labs/polyglot-playground
flox activate -r flox-labs/rust-dev

Every tool lands on PATH the moment you activate.

Environments

Directory Toolchain FloxHub
cxx C/C++ — gcc/clang, cmake, ninja, gdb/lldb, valgrind flox-labs/cxx
rust-dev Rust — rustc, cargo, clippy, rustfmt, rust-analyzer flox-labs/rust-dev
go Go — go, gopls, delve, golangci-lint flox-labs/go
zig Zig — zig, zls flox-labs/zig
node Node.js + TypeScript flox-labs/node
python3 Python — python, uv flox-labs/python3
ruby Ruby — ruby, bundler flox-labs/ruby
php PHP — php, composer flox-labs/php
perl Perl — perl, cpanm, perltidy, perlcritic flox-labs/perl
lua Lua — lua, luarocks flox-labs/lua
erlang Erlang + Elixir (BEAM) — rebar3, mix, LSPs flox-labs/erlang
haskell Haskell — ghc, cabal, stack flox-labs/haskell
kotlin Kotlin (JVM) — kotlin, gradle flox-labs/kotlin
clojure Clojure (JVM) — clojure, leiningen flox-labs/clojure
scala Scala (JVM) — scala, sbt, metals flox-labs/scala
datascience R + Julia — gfortran flox-labs/datascience

Each <lang>/ is a self-contained Flox environment. polyglot/ declares no packages of its own — it [include]s all sixteen by path.

Layout

polyglot-playground/
├── polyglot/      # composer: includes the 16 leaves by path
├── cxx/  rust-dev/  go/  zig/                     # compiled / systems
├── node/  python3/  ruby/  php/  perl/  lua/       # scripting / dynamic
├── kotlin/  clojure/  scala/                       # JVM
├── erlang/  haskell/  datascience/                 # BEAM · functional · data
├── README.md
└── polyglot/README.md   # composed-environment reference

Compose your own stack

Don't need all sixteen? A composed environment is just a manifest with an [include] block and nothing else. Point it at the leaves you want — by FloxHub handle (works anywhere) or, inside this repo, by path (what polyglot/ does):

# jvm-stack/.flox/env/manifest.toml
[include]
environments = [
  { remote = "flox-labs/kotlin" },   # or { dir = "../kotlin" } within this repo
  { remote = "flox-labs/clojure" },
  { remote = "flox-labs/scala" },
]

flox activate yields Kotlin + Gradle, Clojure + Leiningen, and Scala + sbt + Metals on a shared JDK. Swap the list for a systems stack (cxx + rust-dev), a data stack (python3 + datascience), or whatever a project needs. Includes merge at build time: on an install-ID conflict the last include wins, and the composer's own [install] beats every include.

Common tasks

Every flox command acts on one environment — the one in the current directory, or whichever you name with -d <dir>. In this repo that's either a leaf (rust-dev/, cxx/, …) or the composer (polyglot/), and which you target matters:

  • A leaf is the toolchain's definition. Change it and you change that toolchain for everyone who uses it — anyone activating the leaf, and every composed stack that includes it (after a flox include upgrade). Put things here that genuinely belong to the language.
  • The composer (polyglot/) affects only the composed stack, and its own [install] wins over the includes — so it's where you add a stack-wide tool, or pin/override a single package, without touching any leaf.

Activate — one toolchain or the whole stack:

flox activate -d rust-dev     # just the Rust toolchain
flox activate -d polyglot     # all sixteen        (or: cd into the dir and `flox activate`)

Add or override a tool — pick the target deliberately:

flox install -d polyglot ripgrep       # a tool for the whole composed stack; leaves untouched
flox install -d rust-dev cargo-watch   # part of the Rust toolchain itself — every rust-dev user gets it
flox install -d polyglot nodejs@20     # composer override beats the node leaf's version, for this stack only

Upgrade one axis — packages are grouped, so you bump them independently (again, per environment):

flox upgrade -d rust-dev rust      # just the Rust toolchain
flox upgrade -d cxx shared         # just the shared plumbing (git, openssl, …)

Edit a leaf, then refresh the composer:

flox edit -d cxx -f cxx/.flox/env/manifest.toml   # change the leaf
flox include upgrade -d polyglot cxx              # pull the change into the composed stack

Versioning & rollback — in this repo it's plain git (every leaf and the composer are text manifests); on FloxHub every push is a generation you can inspect or pin to (flox generations list -r flox-labs/<name>, flox pull --copy flox-labs/<name>). Either way, updates are targeted, reviewable diffs — no image rebuilds.

Standalone and on FloxHub

This repo is self-contained: polyglot/ composes its siblings by path, with no dependency on FloxHub — git clone and go. The identical environments are also published on FloxHub under flox-labs/*, so any flox activate -r flox-labs/<name> runs the same thing without cloning.

How it works

A leaf is just a manifest.toml. Packages are sorted into groups so each can be upgraded on its own:

[install]
python3.pkg-path = "python313Full"
python3.pkg-group = "python"          # the language's own runtime + tooling
gcc.pkg-path = "gcc"
gcc.systems = ["x86_64-linux", "aarch64-linux"]
gcc.pkg-group = "compilers-linux"     # gcc on Linux, clang on Darwin
git.pkg-path = "git"
git.pkg-group = "shared"              # git/gh/openssl/pkg-config/zlib/… — common plumbing
  • Package groups are the independent upgrade axes: <language>, shared, compilers-linux (gcc) / compilers-darwin (clang), and darwin (Apple frameworks).
  • Cross-platform — one manifest resolves the right pieces per host: Clang/LLDB on macOS, GCC/GDB/Valgrind on Linux; ARM and x86, no virtualization.
  • No LD_LIBRARY_PATH shims — Flox's ld-floxlib.so exposes $FLOX_ENV/lib as a non-shadowing fallback, so composed leaves never clobber each other's libraries.
  • Compose vs. layer[include] merges at build time (deterministic, shareable); you can also layer ad hoc at runtime (flox activate inside flox activate) for a tool you need right now.

See polyglot/README.md for the composed environment specifically.

Where this is heading

The model above ships each toolchain as an environment. A natural evolution ships each as a package: one built artifact per language that links its tools into a single output and carries its own etc/profile.d script to set the language's env vars and PATH — published to a catalog and kept current by automation. Then flox install your-org/erlang drops a complete, self-configuring toolchain into any environment — no composition, and none of the generic plumbing that really belongs to the base environment or to Flox itself.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors