[Living Document] Yoga@2.0 Release Notes #1257

Closed
opened 2023-04-25 01:09:34 -07:00 by NickGerleman · 6 comments
NickGerleman commented 2023-04-25 01:09:34 -07:00 (Migrated from github.com)

[Living Document] Yoga@2.0 Release Notes

The below document aims as a rolling list of changes which will be incorporated into Yoga version 2.0. This is a new major (breaking) release of Yoga. It is the first new release since 1.19 in May 2021.

The goal is to cut a new branch and release Yoga 2.0.0-beta.1 around the end of June 2023. Apart from the tag, and GitHub release, this is goaled to come with new packages on Maven Central, Cocoapods, and the npmjs registry.

Below describes the set of changes which have been made so far.


We are excited to announce a new major (breaking) version of Yoga. This release contains 198 new commits from 64 contributors, and includes the first significant changes to Yoga in open-source since 2018.

While there has been a long gap in development, the React Native team believes Yoga is a critical tool in delivering the future of React, and we have resumed development of the engine. This release of Yoga is focused on:

  1. Delivering the features we have shipped to React Native to standalone Yoga users
  2. Updating toolchains, packaging, and build systems to make Yoga easier to consume
  3. API changes to allow us to evolve the engine towards conformance

Yoga continuously ships to thousands of surfaces across multiple frameworks at Meta. This version of Yoga corresponds to the version which will be included in React Native 0.73 shipping this fall.

Flexbox gap

The most significant new feature for users on an older stable release of Yoga is the addition of Flexbox gap support. This powers gap, rowGap, and columnGap in React Native 0.71.

// Example.cpp
YGNodeStyleSetGap(node, YGGutterRow, 2.0f);
// Example.java
node.setGap(YogaGutter.ROW, 2.0f);
// Example.ts
node.setGap(Gutter.Row, 2);

Toolchain

Meta uses Buck across its monorepo, but we recognize that Buck has acted as a barrier to be able to use Yoga outside of Meta. Yoga no longer ships build logic for Buck to open-source. We have instead added over 20 new validation jobs to GitHub Actions to continually validate that Yoga builds correctly in common systems and scenarios where Yoga is used in OSS.

New toolchain support includes:

  1. A reference CMake build for Yoga and its unit tests
  2. A modern Gradle build and published AARs
  3. Compatibility with XCode 14.3+
  4. Compatibility with Node 16+
  5. Support for WebAssembly in both Node and browsers
  6. Support for MSVC, higher warning levels, and building without exceptions

Aiming for Conformance

Our team wants to enable engineers to be able to create a single style which renders faithfully across Yoga and web. Conformance is a moving target, with browsers like Chromium regularly making behavior changes to better achieve it. This requires making behavior changes to Yoga which break existing behaviors, for better consistency with the web.

In Yoga 2.0, we’ve generalized UseLegacyStretchBehaviour to a new Errata API, to allow different parts of a Yoga tree to target different conformance levels. This allows rendering part of the tree to be compatible with styles written for web, with other parts compatible with styles written for older versions of Yoga.

Yoga's default behavior going forward is W3C compliance. We recommend users sensitive to the change to set YGErrataClassic, or YGErrataAll if you were already setting UseLegacyStretchBehaviour.

// Example.cpp
YGConfigRef config = YGConfigNew();
YGConfigSetErrata(config, YGErrataClassic);

YGNodeRef node = YGNodeNewWithConfig(config);
// Example.java
YogaConfig config = YogaConfigFactory.create();
config.setErrata(YogaErrata.CLASSIC);

YogaNode node = YogaNodeFactory.create(config);
// Example.ts
const config = Config.create();
config.setErrata(Errata.Classic);

const node = Node.create(config);

Yoga for JavaScript

Yoga’s previous JavaScript bindings are not installable when using Node 12+, making them effectively unusable in today’s JavaScript ecosystem. We now ship a new package with prebuilt binaries and first-class support for TypeScript and modern bundlers.

Two variants are shipped:

  1. An asmjs variant for compatibility
  2. A JS module with embedded WebAssembly (~50% faster)

Both are about 45KB when gzipped.

WebAssembly binaries must be asynchronously compiled and loaded in Chrome. In the absence of universal support for top-level await, we have made the breaking change to require explicitly asynchronously loading Yoga before using it.

import {loadYoga, Align} from 'yoga-layout';

const Yoga = await loadYoga();
const node = Yoga.Node.create();
node.setAlignContent(Align.Center);

The previous behavior of blocking to load the binary can be replicated by importing from the yoga-layout/sync entrypoint, but this is not recommended for new usages, and does not allow using WebAssembly on browsers.

import Yoga, {ALIGN_CENTER} from 'yoga-layout/sync';

const node = Yoga.Node.create();
node.setAlignContent(ALIGN_CENTER);

yoga-layout and yoga-layout/sync try to pick between asmjs and WebAssembly automatically based on the target environment set by your bundler, but you can choose this explicitly as well.

import {loadYoga} from 'yoga-layout/wasm-async';

Note: the yoga-layout package requires your bundler and typechecker to configured to be able to follow the package exports field.

Deprecations and removals

YogaKit and YogaLayout ViewGroup

We are deprecating, YogaKit and the YogaLayout ViewGroup. These libraries allow initegrating Yoga directly with UIKit and the Android view system, but are not widely used by Meta in production. We are instead focusing on higher-level libraries using Yoga like Litho and React Native. Because we aren’t in a place to continue development, or validate contributions, we are discontinuing development. These libraries will not receive future updates beyond the Yoga release-v2.0 branch.

UseLegacyStretchBehaviour

The functions to manipulate UseLegacyStretchBehaviour have been deprecated. Previous users of the API should now set an appropriate errata level, like YGErrataAll to opt-out of all future conformance fixes.

C# bindings

C# bindings were contributed to the Yoga repo but have since degraded. The bindings have not had working build validation, or a consistent contributor. We have removed them from the Yoga repo, but we will continue to provide a public C ABI for others to build bindings on top of.

Private C++ APIs

Yoga’s header structure has historically allowed the inclusion of concrete internal structures like YGStyle or YGNode. We will begin to enforce that users instead rely on the public C APIs provided by #include <yoga/Yoga.h>. Other C++ APIs may change without notice.

// Public API (GOOD)
#include <yoga/Yoga.h>

YGConfigRef config = YGConfigNew();
YGConfigSetPointScaleFactor(config, 1.0f);
// Private API (BAD)
#include <yoga/YGConfig.h>

YGConfig config{yogaLogger_};
config.pointScaleFactor = 1.0f;

C++ 11 Support

Yoga now requires a compiler which supports C++ 14. This will likely be bumped to C++ 17 in a future minor release.

How do I get it?

For users who don’t want to build from source, new Yoga packages have been published to the npmjs registry, Maven Central, and CocoaPods. We are initially labeling these packages as beta, because of the amount of new infrastructure, but don’t expect to need major changes before being able to remove the label.

// package.json
dependencies: {
  "yoga-layout": "^2.0.0-beta.1"
}
// build.gradle
dependencies {
  implementation("com.facebook.yoga:yoga:2.0.0-beta.1")
}
# Podfile
pod 'Yoga', '~> 2.0.0-beta.1'

Acknowledgements

Yoga 2.0 contains major external contributions from @intergalacticspacehighway, @jacobp100, @jeetiss and @nicoburns.

# [Living Document] Yoga@2.0 Release Notes The below document aims as a rolling list of changes which will be incorporated into Yoga version `2.0`. This is a new major (breaking) release of Yoga. It is the first new release since `1.19` in May 2021. The goal is to cut a new branch and release Yoga `2.0.0-beta.1` around the end of June 2023. Apart from the tag, and GitHub release, this is goaled to come with new packages on Maven Central, Cocoapods, and the npmjs registry. Below describes the set of changes which have been made so far. ---- We are excited to announce a new major (breaking) version of Yoga. This release contains 198 new commits from 64 contributors, and includes the first significant changes to Yoga in open-source since 2018. While there has been a [long gap in development](https://github.com/facebook/yoga/issues/1151), the React Native team believes Yoga is a critical tool in delivering the future of React, and we have resumed development of the engine. This release of Yoga is focused on: 1. Delivering the features we have shipped to React Native to standalone Yoga users 2. Updating toolchains, packaging, and build systems to make Yoga easier to consume 3. API changes to allow us to evolve the engine towards conformance Yoga continuously ships to thousands of surfaces across multiple frameworks at Meta. This version of Yoga corresponds to the version which will be included in React Native 0.73 shipping this fall. ## Flexbox gap The most significant new feature for users on an older stable release of Yoga is the addition of Flexbox gap support. This powers `gap`, `rowGap`, and `columnGap` in React Native 0.71. ```cpp // Example.cpp YGNodeStyleSetGap(node, YGGutterRow, 2.0f); ``` ```java // Example.java node.setGap(YogaGutter.ROW, 2.0f); ``` ```ts // Example.ts node.setGap(Gutter.Row, 2); ``` ## Toolchain Meta uses [Buck](https://buck.build/) across its monorepo, but we recognize that Buck has acted as a barrier to be able to use Yoga outside of Meta. Yoga no longer ships build logic for Buck to open-source. We have instead added over 20 new validation jobs to GitHub Actions to continually validate that Yoga builds correctly in common systems and scenarios where Yoga is used in OSS. New toolchain support includes: 1. A reference CMake build for Yoga and its unit tests 1. A modern Gradle build and published AARs 1. Compatibility with XCode 14.3+ 1. Compatibility with Node 16+ 1. Support for WebAssembly in both Node and browsers 1. Support for MSVC, higher warning levels, and building without exceptions ## Aiming for Conformance Our team wants to enable engineers to be able to create a single style which renders faithfully across Yoga and web. Conformance is a moving target, with browsers like Chromium regularly making behavior changes to better achieve it. This requires making behavior changes to Yoga which break existing behaviors, for better consistency with the web. In Yoga 2.0, we’ve generalized `UseLegacyStretchBehaviour` to a new [Errata API](https://github.com/facebook/yoga/issues/1247), to allow different parts of a Yoga tree to target different conformance levels. This allows rendering part of the tree to be compatible with styles written for web, with other parts compatible with styles written for older versions of Yoga. Yoga's default behavior going forward is W3C compliance. We recommend users sensitive to the change to set `YGErrataClassic,` or `YGErrataAll` if you were already setting `UseLegacyStretchBehaviour`. ```cpp // Example.cpp YGConfigRef config = YGConfigNew(); YGConfigSetErrata(config, YGErrataClassic); YGNodeRef node = YGNodeNewWithConfig(config); ``` ```java // Example.java YogaConfig config = YogaConfigFactory.create(); config.setErrata(YogaErrata.CLASSIC); YogaNode node = YogaNodeFactory.create(config); ``` ```ts // Example.ts const config = Config.create(); config.setErrata(Errata.Classic); const node = Node.create(config); ``` ## Yoga for JavaScript Yoga’s previous JavaScript bindings are not installable when using Node 12+, making them effectively unusable in today’s JavaScript ecosystem. We now ship a new package with prebuilt binaries and first-class support for TypeScript and modern bundlers. Two variants are shipped: 1. An asmjs variant for compatibility 1. A JS module with embedded WebAssembly (~50% faster) Both are about 45KB when gzipped. WebAssembly binaries must be asynchronously compiled and loaded in Chrome. In the absence of universal support for top-level await, we have made the breaking change to require explicitly asynchronously loading Yoga before using it. ```ts import {loadYoga, Align} from 'yoga-layout'; const Yoga = await loadYoga(); const node = Yoga.Node.create(); node.setAlignContent(Align.Center); ``` The previous behavior of blocking to load the binary can be replicated by importing from the `yoga-layout/sync` entrypoint, but this is not recommended for new usages, and does not allow using WebAssembly on browsers. ```ts import Yoga, {ALIGN_CENTER} from 'yoga-layout/sync'; const node = Yoga.Node.create(); node.setAlignContent(ALIGN_CENTER); ``` `yoga-layout` and `yoga-layout/sync` try to pick between `asmjs` and `WebAssembly` automatically based on the [target environment](https://webpack.js.org/guides/package-exports/#target-environment) set by your bundler, but you can choose this explicitly as well. ```ts import {loadYoga} from 'yoga-layout/wasm-async'; ``` > Note: the `yoga-layout` package requires your bundler and typechecker to configured to be able to follow the package `exports `field. ## Deprecations and removals ### YogaKit and YogaLayout ViewGroup We are deprecating, `YogaKit` and the `YogaLayout` ViewGroup. These libraries allow initegrating Yoga directly with UIKit and the Android view system, but are not widely used by Meta in production. We are instead focusing on higher-level libraries using Yoga like [Litho](https://fblitho.com/) and [React Native](https://reactnative.dev/). Because we aren’t in a place to continue development, or validate contributions, we are discontinuing development. These libraries will not receive future updates beyond the Yoga `release-v2.0` branch. ### UseLegacyStretchBehaviour The functions to manipulate `UseLegacyStretchBehaviour` have been deprecated. Previous users of the API should now set an appropriate errata level, like `YGErrataAll` to opt-out of all future conformance fixes. ### C# bindings C# bindings were contributed to the Yoga repo but have since degraded. The bindings have not had working build validation, or a consistent contributor. We have removed them from the Yoga repo, but we will continue to provide a public C ABI for others to build bindings on top of. ### Private C++ APIs Yoga’s header structure has historically allowed the inclusion of concrete internal structures like `YGStyle` or `YGNode`. We will begin to enforce that users instead rely on the public C APIs provided by `#include <yoga/Yoga.h>`. Other C++ APIs may change without notice. ```cpp // Public API (GOOD) #include <yoga/Yoga.h> YGConfigRef config = YGConfigNew(); YGConfigSetPointScaleFactor(config, 1.0f); ``` ```cpp // Private API (BAD) #include <yoga/YGConfig.h> YGConfig config{yogaLogger_}; config.pointScaleFactor = 1.0f; ``` ### C++ 11 Support Yoga now requires a compiler which supports C++ 14. This will likely be bumped to C++ 17 in a future minor release. ## How do I get it? For users who don’t want to build from source, new Yoga packages have been published to the npmjs registry, Maven Central, and CocoaPods. We are initially labeling these packages as beta, because of the amount of new infrastructure, but don’t expect to need major changes before being able to remove the label. ```jsonc // package.json dependencies: { "yoga-layout": "^2.0.0-beta.1" } ``` ```gradle // build.gradle dependencies { implementation("com.facebook.yoga:yoga:2.0.0-beta.1") } ``` ```rb # Podfile pod 'Yoga', '~> 2.0.0-beta.1' ``` ## Acknowledgements Yoga 2.0 contains major external contributions from [@intergalacticspacehighway](intergalacticspacehighway), [@jacobp100](https://github.com/jacobp100), [@jeetiss](https://github.com/jeetiss) and [@nicoburns](https://github.com/nicoburns).
jacobp100 commented 2023-04-25 01:25:52 -07:00 (Migrated from github.com)

Exciting stuff!

Exciting stuff!
fredemmott commented 2023-06-19 05:54:31 -07:00 (Migrated from github.com)

With the public/private C API split and the possibility of a C++ API, it'd be great to bring back documentation of the C API (and add it for C++), which was removed in 2017.

With the public/private C API split and the possibility of a C++ API, it'd be great to bring back documentation of the C API (and add it for C++), which was removed in 2017.
NickGerleman commented 2023-06-20 13:15:46 -07:00 (Migrated from github.com)

With the public/private C API split and the possibility of a C++ API, it'd be great to bring back documentation of the C API (and add it for C++), which was removed in 2017.

I also think this would be useful. I have been doing a little bit of work to try to renovate the static documentation site (mainly to validate the newer JS bindings), and there is a drought in usable documentation at the moment.

Some of that should also probably live in the source code, and beyond that we have yet another problem where the code generation for enums doesn't allow propagating comments, which is confusing.

> With the public/private C API split and the possibility of a C++ API, it'd be great to bring back documentation of the C API (and add it for C++), which was removed in 2017. I also think this would be useful. I have been doing a little bit of work to try to renovate the static documentation site (mainly to validate the newer JS bindings), and there is a drought in usable documentation at the moment. Some of that should also probably live in the source code, and beyond that we have yet another problem where the code generation for enums doesn't allow propagating comments, which is confusing.
Saadnajmi commented 2023-06-29 21:41:14 -07:00 (Migrated from github.com)

Compatibility with XCode 13.4

Did you mean 14.3?

> Compatibility with XCode 13.4 Did you mean 14.3?
NickGerleman commented 2023-06-29 22:15:24 -07:00 (Migrated from github.com)

Compatibility with XCode 13.4

Did you mean 14.3?

Good catch, fixed 🙂.

> > Compatibility with XCode 13.4 > > Did you mean 14.3? Good catch, fixed 🙂.
NickGerleman commented 2023-06-30 16:43:25 -07:00 (Migrated from github.com)

All of the packages are now out, and we have a GitHub Release: https://github.com/facebook/yoga/releases/tag/v2.0.0-beta.1

I opened https://github.com/facebook/yoga/issues/1320 to solicit feedback on the release (this repo does not currently have GitHub Discussions).

All of the packages are now out, and we have a GitHub Release: https://github.com/facebook/yoga/releases/tag/v2.0.0-beta.1 I opened https://github.com/facebook/yoga/issues/1320 to solicit feedback on the release (this repo does not currently have GitHub Discussions).
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: DaddyFrosty/yoga#1257
No description provided.