Toffee Vs. Island/Darwin

The Elements compiler has two compiler back-ends that support building Cocoa projects.

  • The Toffee compiler is the current default back-end for Cocoa projects, and it directly and exclusively targets the Objective-C runtime that is the back-bone of Apple's platforms. Binaries compiled with Toffee will be virtually indistinguishable from those created with Apple's Clang compiler for Objective-C.

  • The Island/Darwin back-end is allows you to mix Objective-C code with Elements' own object model (shared between all the Island-backed platforms) as well as (in the near future) the new Swift object model.

Benefits of the Toffee Mode

Toffee is the current default back-end for targeting macOS, iOS and the other Apple platforms. It has been around for over a decade, is time-proven and well tested on all platforms. Many of our own internal and external projects and products are compiled using Toffee, including the significant code base that makes up our Fire IDE.

  • Maps directly to Objective-C, so your generated projects are as indistinguishable as those created with Xcode and Clang as they can get.

Drawbacks of the Toffee Mode

  • No support for interfaces on Structs
  • No access to Island RTL
  • No access to the Island Object Model – all objects are Cocoa classes descending from NSObject
  • No access to (forthcoming) Swift Object Model

Benefits of the Island/Darwin Mode

  • Newer compiler infrastructure
  • Fewer platform limitations (e.g. such as interfaces on records/structs) than on Toffee
  • Access to the Island RTL API, for easier code sharing with other Island platforms.
  • Mix more efficient Island Object Model classes with Cocoa classes seamlessly.
  • In the future1, access to Swift Object Model types, including Swift-only Apple Frameworks.

Drawbacks of the Island/Darwin Mode

  • Rougher and less-well tested compiler toolchain
  • Internals can be "more messy" and feel less native Cocoa-like, when mixing Island and Cocoa object models
  • (For now) no watchOS support due to limited threading APIs that prevent the use of our GC.

Which Back-End Should You Use?

Right now, Toffee is the right back-end to use if your main goal is to create a native macOS, iOS, tvOS or watchOS GUI application or library.

It provides you with access to all the Cocoa APIs and lower-level C APIs you need and is well-tested and widely used internally and by other Elements users. The executables and code generated with Toffee will be as close to that generated by Xcode and Clang as can be imagined.

Toffee code runs closer to the Objective-C runtime, because every class you create is a pure Cocoa class, and Elements RTL on Toffee is designed on top of Cocoa APIs, for example toll-free bridging types such as List and Dictionary to Apple-provided Foundartion types.

The Island/Darwin back-end is the right option to use if you are porting existing Island/Windows or Island/Linux code, or starting a low-level project targeting all three of those platforms where having the same type semantics provided by the shared Island Object Model and the availability of the Island RTL APIs is helpful. (Of course Elements RTL provides a common set of APIs, for all platforms that is worthy considering, if the shared API is the main driving factor).

"ToffeeV2" Mode

Our long term goal is to move all Cocoa development to the Island/Darwin back-end. A "best-of-both-worlds" mode called "ToffeeV2" is provided to make this migration easier.

ToffeeV2 mode can be enabled by setting the "Use Toffee V1" setting in a Toffee project to False (it defaults to True).

ToffeeV2 mode will switch your project to use the Island/Darwin back-end, but should let most existing Toffee code compile as is, by tweaking the default assumptions. For example, just as in regular Toffee mode, classes that do not specify ancestor or an Object Model will default to Cocoa rather than Island classes.

Please read more about ToffeeV2 mode here.


There are four steps between "Toffee" and pure "Island":

Mode/Setting Compiler User-declared Classes are? Elements RTL?
Toffee Toffee Everything is Cocoa and every class is an Objective-C runtime ("Cocoa") class. Most Elements RTL types map to native Cocoa classes, for toll-free inter-op with the SDKs.
ToffeeV2 Island User-declared classes are Cocoa by default; you can interact with Island classes, and mark your own classes with the [Island] attribute to make them Island native classes. Elements RTL still maps to Cocoa objects.
Island + DefaultObjectModel=Cocoa Island User-declared classes are still Cocoa by default. Elements RTL now maps to Island RTL objects (e.g. List<T> is not an NSArray, but maps to the List from Island RTL).
Island Island User-declared classes are Island by default. You can still interact with Cocoa classes, and mark your own classes with the [Cocoa] attribute to make them Objective-C-native classes. Elements RTL maps to Island RTL objects

See Also

  1. Swift runtime object model support will be added once Apple Swift has stabilized both its ABI and its Module format. In theory, this features has been delivered by Apple in late 2019, but it is not very well documented and we have doubts about its long-term stability. We are slowly investigating and adding support for it, over time.