Est. 2005 Intermediate

Fantom

A portable, Java-like language built by two building-automation architects who wanted one codebase to run on the JVM and in the browser, with actor concurrency, enforced immutability, and both static and dynamic method calls.

Created by Brian Frank and Andy Frank

Paradigm Multi-paradigm: object-oriented, functional (closures), and actor-based concurrency
Typing Static and strong, with an opt-in dynamic call operator; type annotations required on signatures, inferred for locals
First Appeared 2005
Latest Version 1.0.83 (12 March 2026)

Fantom is a general-purpose, object-oriented language created by brothers Brian and Andy Frank. Its defining bet is portability of a very particular kind: rather than targeting a single virtual machine, Fantom compiles to its own intermediate bytecode - fcode - which is translated at runtime into Java bytecode, and separately transpiled to JavaScript for the browser. One source tree, two live runtimes.

That premise has aged unusually well. Fantom arrived before Kotlin, before Scala.js, before TypeScript, and before the current consensus that a language ought to be able to reach the browser. It is also, quietly, still shipping: the most recent build, 1.0.83, is dated 12 March 2026, more than twenty years after the first entry in the project’s change log.

What Fantom is not is popular. It has never had a corporate sponsor pushing it, never had a breakout framework, and never appeared meaningfully in language popularity indices. Its survival rests instead on something narrower and more durable - a substantial commercial product built on it, maintained by one of its own authors.

History & Origins

Two architects with a specific complaint

Brian and Andy Frank came to language design from industry rather than academia. Brian was a co-founder of Tridium - a Richmond, Virginia company founded in the mid-1990s, acquired by Honeywell in 2005 - and the lead architect of its Niagara Framework, a Java platform for integrating building-automation devices across protocols like BACnet, LonWorks and Modbus. That is systems-integration work: long-lived software, heterogeneous deployment targets, and a lot of time spent inside Java’s standard library.

The frustrations that came out of that experience are visible throughout Fantom’s design rationale. The project’s Why Fantom? document is blunt about the standard libraries it was reacting against - it calls Java’s Calendar class “the poster child for APIs which are just miserable to use”, and points out that Fantom condenses the several dozen classes of java.io into four: File, Buf, InStream, OutStream, with buffering and text handling built in rather than bolted on through decorators. It dismisses Java’s checked exceptions as “evil syntax salt”. These are not the complaints of theorists; they are the complaints of people who had written a great deal of Java.

Fan

Work began in September 2005, with the change log’s first entry recording the start of a Java-hosted parser for a language then called Fan - named for The Fan, the early-twentieth-century Richmond neighbourhood where the brothers lived, and which the FAQ describes approvingly as dating from a time “when urban planning was human-centric as opposed to automobile-centric.”

The first official build, 1.0.1, is dated 1 January 2007. By build 1.0.10 that July, the last of the Java-based compiler code had been removed and the compiler was self-hosted in Fan itself. The project became public in 2008, and the FAQ states that Fantom has been used in commercial software since that year.

The name lasted until November 2009, when the project renamed itself Fantom. The reason was mundane and completely understandable: a programming language named “Fan” is impossible to search for.

Design Philosophy

Portability as the first principle

Most languages pick a runtime and inherit its worldview. Fantom deliberately refuses to. Its standard library is designed as an abstraction layer that does not expose Java, .NET or JavaScript specifics, precisely so that a pod written purely in Fantom stays portable. The documentation has long noted that this in principle leaves the door open to further backends - LLVM, WebAssembly, native targets.

In practice, the JVM is the primary runtime and the browser the secondary one; the project’s homepage today describes Fantom simply as “a portable language that runs on the JVM and modern web browsers.” A .NET CLR backend was built and can emit CIL from fcode, but the official documentation describes it as prototype status and it should not be treated as a production target. Beyond the JVM and browser runtimes named on the project’s own site, other platform and architecture support is best confirmed against the current distribution rather than assumed.

Static typing, with an escape hatch

Fantom’s typing stance is a genuine middle position rather than a compromise nobody wanted. Method signatures and fields must carry type annotations; local variables are inferred with :=. Then there are two call operators:

obj.foo()    // static call - checked at compile time
obj->foo()   // dynamic call - dispatches through Obj.trap at runtime

The -> operator desugars into a call to Obj.trap, which any class can override. That gives duck typing, dynamic proxies and DSL-style dispatch without abandoning static checking everywhere else - a single character marks exactly where the compiler stops helping you.

Generics, deliberately limited

Fantom does not offer general-purpose parameterised types. It offers built-in generics on exactly three classes - List, Map and Func - with dedicated syntax:

Int[] nums := [1, 2, 3]
Str:Int ages := ["alice":34, "bob":29]
|Int a, Int b -> Int| add := |Int a, Int b -> Int| { a + b }

The reasoning is stated plainly in the design docs: the overwhelming majority of real-world generic code is collections and functions, and supporting only those cases avoids importing the complexity that full parameterisation brings with it. It is a pragmatic trade, and one of the choices people most often argue with.

Immutability and actors

Concurrency in Fantom is built on immutability enforced by the language rather than by convention. A const class is transitively immutable, static fields must be immutable, and only immutable values may be passed between actors:

const class Point
{
  new make(Int x, Int y) { this.x = x; this.y = y }
  const Int x
  const Int y
}

On top of that sits an Erlang-style actor model - message passing to lightweight actors backed by a thread pool, rather than shared mutable state guarded by locks:

actor := Actor(group) |Int msg->Int| { msg + 1 }
for (i:=0; i<5; ++i) echo(actor.send(i).get)

send returns a future, so callers can fire and forget or block on the result. This design landed well before actors and structured concurrency became mainstream concerns on the JVM.

Key Features

Familiar syntax, small surprises

Fantom’s syntax is C-family and reads close to Java or C#:

class HelloWorld
{
  static Void main()
  {
    echo("hello world")
  }
}
class Person
{
  Str name
  Int age
  Int yearsToRetirement(Int retire := 65) { return retire - age }
}

Note the default parameter value on a method - a small ergonomic win Java lacked entirely at the time.

Literals for the things you actually type

Fantom gives first-class literal syntax to constructs that most languages make you build by hand:

[0, 1, 2]            // List
[1:"one", 2:"two"]   // Map
5sec                 // Duration
`/dir/file.txt`      // Uri

Durations and URIs as literals are a recurring theme: things that are conceptually values should look like values.

Closures and functional style

list := ["red", "yellow", "orange"]
list.each |Str color| { echo(color) }

10.times |i| { echo(i) }

Closures use pipe-delimited parameter lists, and the language’s collection APIs are built around them. Again, worth placing in time - this shipped years before Java 8.

Uniform numerics

Fantom has Int and Float, and both are 64-bit. There is no short, no long, no double-versus-float decision to make. Decimal exists separately for exact arithmetic. The documentation’s argument is that the precision menu offered by C-derived languages buys very little for most application code and costs a great deal of attention.

Pods

The unit of both namespace and deployment is the pod - a ZIP archive containing fcode, documentation and resources, filling the role of a Java package and a JAR simultaneously. The Java runtime reads a pod and emits Java bytecode at runtime; the .NET runtime, in its prototype form, emits CIL the same way. A pod written entirely in Fantom is portable across runtimes without recompilation.

Evolution

Fantom’s version numbering is its own commentary on the project. The scheme is major.minor.build.patch, and after more than two decades it remains on the 1.0.x line - the build counter has simply kept climbing, from 1.0.1 in 2007 to 1.0.83 in 2026. There has been no 2.0, no rewrite, and no breaking-change event.

The releases themselves show where attention has gone:

BuildDateFocus
1.0.11 Jan 2007First official build
1.0.26Apr 2008Decimal type, float literal syntax
1.0.43May 2009FWT ported to JavaScript
1.0.70Nov 2017Node.js becomes the default JS runtime
1.0.77Sep 2021ASN.1 and crypto pods, TLS
1.0.78Apr 2022Graphics and canvas APIs
1.0.79Jul 2023YAML API, file operations
1.0.80Apr 2024ECMAScript class-based JS backend, JWT/JWK
1.0.816 Dec 2024Markdown pod, console API, static once methods
1.0.8226 Jun 2025fanc Java-source transpiler, generics improvements
1.0.8312 Mar 2026JS promises, YAML writer, weak-reference logging

The through-line is the JavaScript backend, which has been rebuilt more than once - from the original transpiler, to Node.js as the default runner in 2017, to a full ECMAScript-class-based redesign in 2024. The fanc transpiler added in 2025 points in another direction again: emitting readable Java source rather than runtime-generated bytecode.

Current Relevance

Fantom occupies an unusual position. By any adoption metric it is a niche language - it has never registered meaningfully in the TIOBE or RedMonk rankings, its community is small enough to fit in a single mailing list, and its library ecosystem, largely the work of Fantom-Factory, is measured in dozens of pods rather than thousands.

But it is not abandoned, and the reason is structural. SkyFoundry, the company Brian Frank founded after Tridium, builds SkySpark - a commercial analytics platform for building, energy and equipment data - on Fantom. Haxall, the open source framework SkyFoundry published as SkySpark’s foundational layer, is written in Fantom and released under the same Academic Free License 3.0 as the language itself. That means Fantom has something most small languages never get: a maintainer whose own commercial product depends on it continuing to work, and whose engineers are among its contributors.

The result is a language with an unusual risk profile. It is unlikely to grow, and equally unlikely to stop.

Tooling reflects the same scale. The F4 IDE - Eclipse-based, itself written largely in Fantom, originally from Xored and since maintained by community contributors - remains the main full development environment, alongside editor plugins. There is no official Docker image and no package-manager one-liner on most platforms; installation generally means downloading a distribution from fantom.org and putting it on your path.

Why It Matters

Fantom is worth studying less for what it achieved than for what it got right early, and independently.

It solved the portability problem before the industry admitted there was one. Compiling one source language to both JVM bytecode and JavaScript was a fringe idea in 2007. Scala.js arrived in 2013; Kotlin’s multiplatform story came later still. Fantom’s answer - an intermediate bytecode plus a deliberately runtime-neutral standard library - is essentially the architecture the industry converged on.

It took immutability seriously as a language feature. const classes with transitive immutability, immutable statics, and immutability as the precondition for message passing form a coherent system rather than a set of library conventions. That combination is now recognisable as the right answer; in 2007 it was a bet.

It showed that static and dynamic typing can share a program. The . versus -> split is a small piece of syntax with large consequences: it lets a single codebase be strictly checked where it should be and duck-typed where that genuinely helps, with the boundary visible in the source. Gradual typing systems since have generally been more elaborate and less legible.

And it demonstrates what actually sustains a small language. Fantom has outlasted dozens of better-funded contemporaries not through marketing or community growth, but because a real business runs on it. That is a less romantic survival mechanism than a thriving open source community - and, on the evidence, a considerably more reliable one.

Timeline

2005
The earliest entry in Fantom's own change log is dated September 2005: "Begin work on Java version of Fan parser." The language was originally called Fan, after The Fan, the Richmond, Virginia neighbourhood where Brian and Andy Frank lived
2007
Build 1.0.1, recorded in the change log as the "first official build", is dated 1 January 2007. It shipped with both a Ruby and a Fan build script, the compiler still being bootstrapped out of Java
2007
Build 1.0.10 in July removes the last of the old Java-based compiler code, completing the move to a self-hosted, Fantom-written compiler
2008
The project goes public. Build 1.0.26 in April adds the Decimal type and the requirement that float literals carry an explicit suffix. The language FAQ states that Fantom has been used in commercial software since 2008
2009
Build 1.0.43 in May ports FWT, the Fan Widget Toolkit, to JavaScript - the first serious demonstration of the same source compiling to both the JVM and the browser
2009
In November the project is renamed from Fan to Fantom, after community complaints that a language called "Fan" was effectively unsearchable
2017
Build 1.0.70 in November makes the Node.js-based runtime the default way to execute Fantom JavaScript outside a browser
2022
Build 1.0.78 in April lands a substantial new graphics API with canvas rendering
2023
Build 1.0.79 in July adds a YAML API along with expanded file operations
2024
Build 1.0.80 in April rebuilds the JavaScript backend around ECMAScript classes and adds JWT/JWK crypto support; build 1.0.81 in December adds a markdown pod, a console API and static once methods
2025
Build 1.0.82 in June introduces fanc, a transpiler that emits Java source from Fantom code, alongside improved generics handling
2026
Build 1.0.83 ships on 12 March with JavaScript promise support, a YAML writer, new string utilities and weak-reference-based logging - more than twenty years after the first parser commit, the release cadence continues

Notable Uses & Legacy

SkySpark (SkyFoundry)

SkyFoundry's commercial analytics platform for building, energy and equipment data. Brian Frank, one of Fantom's two creators, is SkyFoundry's founder and SkySpark's software architect, and the product is built on the Fantom runtime. It is generally regarded as the largest body of production Fantom code in existence.

Haxall

An open source IoT and data-historian framework published by SkyFoundry as the foundational layer of SkySpark, written in Fantom and running on both the JVM and JavaScript. Haxall embeds Axon, a functional scripting engine, and extensions written for Haxall drop straight into a SkySpark runtime.

Fantom-Factory / Alien-Factory

Steve Eynon's library ecosystem, hosting dozens of community pods covering IoC containers, the afBedSheet web framework, database drivers and more, published through the Eggbox pod repository. For years this was the practical answer to "what third-party libraries does Fantom have?"

F4 IDE

An Eclipse-based Fantom IDE, itself written largely in Fantom, originally developed by Xored and subsequently maintained by community contributors. It remains the main full IDE for the language and is a sizeable self-hosted demonstration of Fantom on the desktop.

Escape the Mainframe

A retro vector-graphics game written in Fantom and published by Alien-Factory, which reportedly runs both as a desktop application and, from the same source, in the browser - a demonstration of Fantom's write-once-run-on-JVM-and-JavaScript promise.

Language Influence

Influenced By

Running Today

Run examples using the official Docker image:

docker pull
Last updated: