known as
Old SixtyFPS logo

SixtyFPS 0.1.6 Released

January 21, 2022
Olivier Goffart, Simon Hausmann, and Tobias Hunger

SixtyFPS 0.1.6

Today we're releasing SixtyFPS version 0.1.6, which contains new features and some bug fixes. Let's look at the highlights:

Special Keys

The FocusScope element is used to handle keyboard events. Previously, you would inspect KeyEvent.text to find out which key was pressed; but this only worked for printable characters. Now, we have a Keys namespace to expose most non-printable keys. Use this namespace to handle keyboard events as follows:

FocusScope {
    key-pressed(event) => {
        if (event.text == Keys.Escape) {
            debug("Esc key was pressed");

Sequential Animations

Use the new delay property in animations to time transitions. This forms a building block for sequential animations. We've made a little example that you can view in our online editor, and you can see it live in action below:

Access Model Elements by Index

Use the array syntax, model[index], to access individual elements of models in .60 markup. When data in the model changes, corresponding property bindings are re-evaluated automatically. In the example below, the current theme color is selected by index, and the text color is updated automatically when current-theme changes.

struct Theme := {
    name: string,
    text-foreground: brush,
    // ...
App := Window {
  property <[Theme]> themes: [
      name: "paper",
      text-foreground: black,
      // ...
      name: "dark",
      text-foreground: white,
      // ...

  property <int> current-theme: 1;

  Rectangle {
    // ...
    Text {
      text: "Hello";
      color: themes[current-theme].text-foreground;


We're working on making SixtyFPS run on low-end MCUs. One interesting constraint is memory consumption. To handle this, we implemented an optimization in the compiler that reduces the number of properties by propagating constant values throughout property bindings. We also changed our internal data structures to allow for further optimizations in the future.

Prior to version 0.1.5, we used to inline all components declared in .60 markup into the main application component. This made our implementation easier, but it came at the expense of duplicated generated code in compiler output. Since version 0.1.5, we no longer inline all the components, speeding up the compilation of generated C++ and Rust code. For more details see the weekly summary.

Smaller, Noteworthy Features


We're going to rename the SixtyFPS product soon. Consequently the names in the APIs, the Rust crate names, and the library are going to change. This is a source incompatible change. Therefore we're going to bump our minor version number from 0.1 to 0.2. We're also going to use this opportunity to make a few additional changes to the API and the language. Rest assured that we'll provide you with detailed documentation about what changed and how you can migrate your code.


This release contains over 400 patches, made by 13 different contributors, covering 17 issues in GitHub.

A huge thank you to everyone who contributed! Without your help, we would not be where we are today!

We hope that you'll enjoy upgrading to this new version. If you're using SixtyFPS with Rust and Cargo, just run cargo update to update your application to the latest release. If you're using our CMake integration with FetchContent, update the GIT_TAG entry in your CMakeLists.txt to specify v0.1.6.

For a detailed list of all changes, check out the