Pieter De Baets
90d · built 2026-09-30
Performance
What Pieter De Baets shipped in the selected window, measured in ETV, and how it compares with the 90 days before it.
Effective capacity
−0.1engineers
delivers like 0.9 (0.9x pre-AI)
Output (ETV)
5.9ETV
−41.7% vs 10.1 prior
Features share
23.0%
+9.4 pp vs prior window
Fixes share
7.2%
−3.8 pp vs prior window
Work mix
23% Features55.9% Maintenance12.1% Tests1.9% Docs7.2% Fixes
50 commits over 90 days, ending 2026-09-30.
Daily performance
Daily ETV, stacked by Features, Maintenance, Tests, Docs and Fixes.
Repository spread
Where this developer's commits land. Concentrated work (top1 > 80%) vs polymath spread (top1 < 30%).
| Repo | Commits | ETV |
|---|---|---|
| react-native | 42 | 4.8 |
| react | 4 | 1.1 |
Most impactful commits
Top 10 by ETV in the last 90 days.
- 1.3ETVEnable Kotlin warnings as errors (#58390) Summary: Pull Request resolved: https://github.com/react/react-native/pull/58390 K2 warnings can otherwise accumulate unnoticed across React Native Android targets. Enable `warnings_as_errors_k22` by default for `rn_android_library` and clean up the warnings exposed by the RNTester dependency graph. Generated-source targets opt out where warnings cannot be fixed in checked-in source. Changelog: [Internal] Reviewed By: cortinico Differential Revision: D119096917 fbshipit-source-id: 8604536639acb9dde817afef515be696259c1c51github.com-facebook-react-native · eba7f286 · 2026-09-09
- 0.7ETV[compiler] Support update expressions on captured variables (#37513) ## Summary - support prefix and postfix update expressions on captured variables in both TypeScript and Rust compiler backends - represent updates with explicit `PrefixUpdateLocal`, `PrefixUpdateContext`, `PostfixUpdateLocal`, and `PostfixUpdateContext` HIR variants - model captured updates as mutations so SSA, effect inference, dead-code elimination, and post-render validation preserve their semantics - convert the existing TODO fixtures to passing coverage and add the Airwave-shaped map regression from T286959188 - correct Rust workspace manifest paths in the rust-port documentation ## How did you test this change? - `yarn prettier` - `yarn linc` - `yarn flow dom-node` - `yarn test --silent --no-watchman React-hooks-arity` - `yarn test-www --silent --no-watchman useMemoCache` - `yarn test-www --variant=false --silent --no-watchman useMemoCache` - `node_modules/.bin/tsc --noEmit -p compiler/packages/babel-plugin-react-compiler/tsconfig.json` - `cargo +1.93.1 fmt --manifest-path compiler/Cargo.toml --all -- --check` - `cargo +1.93.1 check --manifest-path compiler/Cargo.toml -p react_compiler -j 1` - targeted Cargo tests for lowering, SSA, inference, optimization, and validation - TypeScript and Rust snapshot runs for `*update-expression*` (11 tests each)github.com-facebook-react · d0a776cd · 2026-09-11
- 0.4ETVAdd IntBuffer and DoubleBuffer entry types to MapBuffer (#57359) Summary: Pull Request resolved: https://github.com/react/react-native/pull/57359 Adds two new MapBuffer entry types, `IntBuffer` and `DoubleBuffer`, for storing homogeneous arrays of ints and doubles compactly in the dynamic data section. Unlike `Map` / map lists, these carry no per-element key/type overhead: a batch of N values costs ~N*elementSize bytes plus a single 4-byte count prefix instead of N 12-byte buckets. The bucket value holds the offset of the array within the dynamic data section. Covers the full surface: the C++ reader (`MapBuffer::getIntBuffer` / `getDoubleBuffer`), the C++ builder (`MapBufferBuilder::putIntBuffer` / `putDoubleBuffer`), and the Kotlin reader API (`MapBuffer.getIntBuffer` / `getDoubleBuffer`, `Entry.intBufferValue` / `doubleBufferValue`). The `DataType` enum gains `IntBuffer = 6` and `DoubleBuffer = 7`, kept in sync across C++ and Kotlin. Changelog: [General][Added] - Add `IntBuffer` and `DoubleBuffer` entry types to MapBuffer for compact homogeneous int/double arrays landed-with-radar-review Reviewed By: zeyap Differential Revision: D109848476 fbshipit-source-id: f9e86b7c094dea796d9a8b725e53eb948c1390cagithub.com-facebook-react-native · e7cadaf9 · 2026-07-03
- 0.4ETVBuffer async CallInvoker work with module calls (#58313) Summary: Pull Request resolved: https://github.com/react/react-native/pull/58313 In bridgeless, native reaches JS by two routes that end in the same `RuntimeScheduler` queue but get there differently. `callFunctionOnModule` goes through the instance's `BufferedRuntimeExecutor`; the `CallInvoker` goes straight to `scheduleTask`. The CallInvoker therefore skips the buffer entirely and can reach the runtime while a module call issued earlier is still parked, unflushed, because the bundle is mid-evaluation. Native code that issues both cannot rely on the order it issued them in, and `Task` is a min-heap on `now() + timeout(priority)` with no insertion tiebreak, so equal priorities do not settle it either. Gives the two channels the same buffering. `BufferedRuntimeExecutor` gains a priority-carrying `execute`, so work routed through it keeps the scheduler priority it was submitted with instead of collapsing to the executor default, and buffered work from both overloads stays in one submission-ordered stream. `BufferedCallInvoker` sits on that executor and becomes the bridgeless `jsCallInvoker` on Android, iOS and macOS. `invokeSync` deliberately keeps going straight to the scheduler: a synchronous call cannot wait for a flush that only happens once the bundle has run. Behind `enableBufferedCallInvoker`, default true. `ReactInstance` picks between the buffered invoker and the existing `RuntimeSchedulerCallInvoker` in one place, so the platform call sites are identical either way and the change is revertible at runtime — it moves when native-issued async work first reaches JS during startup, which is the intended contract but affects every native module. One lifetime hazard this surfaces, worth knowing about beyond this diff: `BufferedRuntimeExecutor` reaches the scheduler through a raw pointer captured at construction, which is safe only while the owning instance is alive. A CallInvoker is routinely held across instance teardown, so `BufferedCallInvoker` guards every async dispatch on a weak reference to the scheduler and drops the work when it has expired — the same contract `RuntimeSchedulerCallInvoker` has. Without that guard this reliably segfaults on a reload. Changelog: [General][Changed] - Async `CallInvoker` work is now buffered alongside callable module calls, so it no longer runs before the JS bundle has finished evaluating Reviewed By: rubennorte Differential Revision: D118456662 fbshipit-source-id: 7c6ccb595d69595721092eeb84b4724809140496github.com-facebook-react-native · 3ca6ea3e · 2026-09-04
- 0.3ETVOptimize MapBuffer representation (#57361) Summary: Pull Request resolved: https://github.com/react/react-native/pull/57361 Broadens the former header-shrink change into a single representation-optimization commit for MapBuffer. It bundles three layout optimizations that were previously split: (1) the header is reduced to a single 2-byte `count` field; (2) multi-byte values are read via `memcpy` so unaligned access is well-defined on all platforms; (3) every dynamic-data entry (`String`, `Map`, `MapBufferList`, `IntBuffer`, `DoubleBuffer`) packs its `[offset][byteLength]` into the bucket's 8-byte value instead of writing an in-band length prefix into the dynamic data section. Net effect: 4 fewer bytes per dynamic entry, one fewer indirection on read (the length is already in the bucket), and every dynamic entry becomes self-delimiting from its bucket alone. No public API change — only the internal serialized representation. Changelog: [Internal] landed-with-radar-review Reviewed By: lenaic, zeyap Differential Revision: D109848478 fbshipit-source-id: 30749aaa1c2d9fc9b1f8684a3b67815ef44632e8github.com-facebook-react-native · 803456d6 · 2026-07-03
- 0.3ETVRoute `enableCppPropsIteratorSetter` through a copy ctor + `RawProps::forEachItem` (#57328) Summary: Pull Request resolved: https://github.com/react/react-native/pull/57328 Today the iterator-setter path in `ConcreteComponentDescriptor::cloneProps` runs three sequential walks over the input — `RawProps::parse(parser)` (builds `keyIndexToValueIndex_` for `convertRawProp`), `static_cast<folly::dynamic>(rawProps)` (materializes a `folly::dynamic` via `jsi::dynamicFromValue` in JSI mode), and then `dynamic.items()` to dispatch `setProp`. Only the third is actually used: `convertRawProp` is never called on the iterator-setter branch, and the `folly::dynamic` materialization exists only as iteration scaffolding. Restructure so the runtime flag picks one of two construction paths up front: - **Iterator-setter** — copy-construct from `sourceProps` via the (re-enabled) `Props` copy ctor, then walk `rawProps` in-place via the new `RawProps::forEachItem` helper and route each entry through `setProp`. `parse()` is skipped entirely; the `folly::dynamic` materialization is skipped in `Mode::JSI`. - **Classic** — unchanged: `parse()` + 3-arg `convertRawProp`-driven ctor. `forEachItem` switches on `RawProps::Mode`: - `Mode::JSI` — walks `value_.asObject(*runtime_).getPropertyNames(...)` and constructs `RawValue` from each `jsi::Value` directly, no `folly::dynamic` in between. - `Mode::Dynamic` — iterates `dynamic_.items()` (same as today). - `Mode::Empty` — no-op. A new `HasIteratorSetterCtor<T>` concept (`std::copy_constructible<T>`) documents the contract and feeds a `static_assert` in `cloneProps`, so a future Props type that deletes its copy ctor fails at compile time rather than silently diverging at runtime between the two flag states. The `RN_SERIALIZABLE_STATE` Props 2.0 accumulation branch keeps its existing dynamic-iteration shape — when `fallbackToDynamicRawPropsAccumulation` is true, `initializeDynamicProps` has already merged the source's rawProps with the input onto `shadowNodeProps->rawProps`, so we iterate that merged dynamic rather than the raw input. The per-field `flag ? sourceProps.X : convertRawProp(...)` ternaries across every Props .cpp file become dead in the flag-on path (the copy ctor handles those fields) but are still functional in the flag-off path. They get removed in a follow-up cleanup; this diff is structurally non-breaking on either flag state. Changelog: [Internal] Reviewed By: zeyap Differential Revision: D109568749 fbshipit-source-id: eae20478418a7dbf7364c73d85d7694d99f1e8f1github.com-facebook-react-native · c1d8ae97 · 2026-07-06
- 0.2ETV[flags] Cleanup enableFragmentRefs feature flag (#37573) ## Summary `enableFragmentRefs` is enabled in every channel, so this inlines the enabled branch and removes the flag from `ReactFeatureFlags` and all of its forks. Most of the diff is mechanical, but a few spots needed care: - Several `case Fragment:` blocks in `ReactFiberCommitWork` had a `// Fallthrough` that was only reachable with the flag off. Where a preceding case falls *into* `Fragment` (the `ViewTransitionComponent` cases), I verified the resulting behavior is unchanged for every remaining flag combination. - `commitAttachRef` in `ReactFiberCommitEffects` becomes a plain `case Fragment: { ... break; }` instead of a conditional fallthrough into `default`. - The `React.Fragment` invalid-prop warning no longer has two variants; it always mentions `key`, `ref`, and `children`. The three related flags — `enableFragmentRefsScrollIntoView`, `enableFragmentRefsInstanceHandles`, and `enableFragmentRefsTextNodes` — are *not* on everywhere yet and are left in place. In tests, `enableFragmentRefs` was stripped from 101 `@gate` pragmas. Combined gates such as `@gate enableFragmentRefs && enableFragmentRefsTextNodes` were reduced rather than removed. One test asserted the absence of a warning under the flag, so it was renamed from `warns for fragments with refs` to `does not warn for fragments with refs`. ## How did you test this change? `yarn lint`, `yarn prettier-check`, and `yarn flow` for `dom-node`, `dom-browser`, and `fabric` all pass. Full test suite run across `experimental`, `stable`, `www-modern`, `www-classic`, and `xplat`, with both `--variant` settings, plus `--persistent`. The remaining failures (Fizz / Flight / FrameScheduling / ClassEquivalence) are pre-existing: I diffed the individual failing test names against the base commit and they are identical.github.com-facebook-react · 00f48cec · 2026-09-10
- 0.2ETVReduce JNI allocations when importing native maps (#58274) Summary: Pull Request resolved: https://github.com/react/react-native/pull/58274 `ReadableNativeMap` materialization copied keys and created temporary JNI references for every imported type. Cache pointers to the stable native values and reuse global `ReadableType` references so importing maps and arrays does less allocation and lookup work. Writable maps can continue mutating after materialization because `folly::dynamic` stores object entries in reference-stable `F14NodeMap` nodes. Changelog: [Internal] Reviewed By: christophpurrer, rubennorte Differential Revision: D118277119 fbshipit-source-id: 955a60ef7f1eb4cb7549d64caa1238416e90b223github.com-facebook-react-native · bf0e377c · 2026-09-04
- 0.2ETVDrop per-field `enableCppPropsIteratorSetter` ternaries from Props ctors (#57418) Summary: Pull Request resolved: https://github.com/react/react-native/pull/57418 With `ConcreteComponentDescriptor::cloneProps` now dispatching to the iterator-setter path via the copy ctor (the prior diffs in the stack), the per-field `flag ? sourceProps.X : convertRawProp(...)` ternaries scattered across every Props copy ctor are dead in the flag-on path (copy ctor handles those fields directly) and redundant in the flag-off path (the runtime check inside the ctor is always false, since cloneProps already filtered the iterator-setter path out before invoking the 3-arg ctor). Strip the ternary wrapper from every Props .cpp file. Each initializer collapses from ```cpp field(ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.field : convertRawProp(ctx, rawProps, "field", sourceProps.field, default)) ``` to just ```cpp field(convertRawProp(ctx, rawProps, "field", sourceProps.field, default)) ``` Also strip: - `YogaStylableProps`: the inverted `if (!flag) { convertRawPropAliases(...); }` wrapper becomes unconditional. - `Props::initialize` (`Props.cpp`): the `nativeId` ternary collapses to the `convertRawProp` form. - `AccessibilityProps` (xplat + react-native-macos): the `if (flag) { copy } else { at()-based resolution }` block in the constructor body collapses to just the `at()`-based resolution — the same reasoning applies (flag-on path never reaches the 3-arg ctor). - Drop `<react/featureflags/ReactNativeFeatureFlags.h>` includes that are no longer referenced. 311 ternaries removed across 20 Props .cpp files (incl. the `third-party/react-native-macos/` mirror and `xplat/instagram/airwave/components/airwavescrollview/cpp/AirwaveScrollViewProps.cpp`). Side benefit: the classic path is now meaningfully cheaper because we no longer do `~30 × ReactNativeFeatureFlags::enableCppPropsIteratorSetter()` calls (each goes through `std::atomic<std::optional<bool>>::load()`) per `cloneProps` invocation per Props class. Changelog: [Internal] Reviewed By: mdvacca Differential Revision: D109583086 fbshipit-source-id: f25783cc7fdcf485ed01f63da9a6eea473bfc1d3github.com-facebook-react-native · 1172a8a5 · 2026-07-06
- 0.2ETVRemove useRefEffect (#58451) Summary: Pull Request resolved: https://github.com/react/react-native/pull/58451 React 19 now supports this natively by returning a cleanup callback from the ref setter. The only caveat is that if a ref handler throws, the runtime will still invoke the ref setter with null on unmount. Changelog: [Internal] Reviewed By: zeyap Differential Revision: D114349280 fbshipit-source-id: 93fb5fb2ded37c0ecc3f803bb558b9e977303b05github.com-facebook-react-native · 5ef40878 · 2026-09-10