Experimental

Prereleases and in-progress engine work from the exp channel. Everything on this page is ahead of the last release — the Indent and News pages only track what has actually shipped.

⚠️ Not a release. Experimental builds are published as GitHub prereleases, so the normal download links keep pointing at the stable release and no existing install is moved onto one by accident. Behaviour here can change, and anything listed below can be withdrawn before it ever reaches stable.
Experimental2026-10-16

Indent 2.4.1-exp — proving that nothing broke

This build is aimed at the exp channel rather than stable. It finishes the low-risk half of the memory work — and, more usefully, makes "nothing broke" something the project can check instead of hope.

Every released behaviour is now pinned

Real programs are captured as the exact text they print: how values format, control flow, functions, errors and classes, the copy-on-write guarantees, and a torture program covering nested functions, generators, inheritance, mutation through aliases, dict ordering, unicode and error messages word for word. Each one is run through both execution engines three times and has to match byte for byte, so the faster path can never quietly disagree with the safe one.

The release check always claimed to compare against recorded performance, but nothing had ever been recorded. 158 measurements are recorded now, with a 15% tolerance — so a slowdown gets caught instead of being noticed months later.

Worth knowing, because none of it was written down

  • say true prints TRUE.
  • Strings inside containers print unquoted.
  • Dict keys print in sorted order.
  • len("héllo 🚀") counts codepoints, not bytes.

What it means for your code

  • Nothing changes. There is no new syntax and no changed behaviour, and there is nothing to do to upgrade.
  • Startup does a couple of dozen fewer allocations, because a table that used to be rebuilt for every run is now built once.
  • A tempting micro-optimisation was measured and rejected. Holding the output stream open for a whole run would have saved a fraction of the ~90 ns a say costs, but in a server it would let one request that prints block every other thread's output.

Full experimental notes →

RoadmapOpen

Still open, and next

  • Faster lookups for variable names and function calls. This changes how the language stores names internally, so it is a one-way change and is being done carefully.
  • More of your code on the compiled path, and smarter compiled code once it is there — fewer decisions left until run time.
  • A smaller, faster value representation, if it is still needed after the two above.
  • An honest caveat: a real memory profile is still missing. Peak memory is measured reliably, but memory is not yet attributed to the feature that spends it.
How it worksChannels

Opting in, and back out

Two channels come out of the same pipeline and the same gates. stable is the default and is what the normal download links point to; exp follows prereleases, published as GitHub prereleases, so a stable install is never moved onto an experimental build by accident.

Install on a channel
curl -fsSL https://indent.xytro.site/install.sh | bash -s -- --channel exp
Switch an existing install, and back
indent --switch-to-exp indent --switch-to-stable indent --channel

indent --version reports the channel — indent 2.4.1 (exp). Both the installer and the switcher verify the release's published checksums before installing anything, and the version being replaced is kept so you can switch back.

Released versions →Read the Docs →GitHub