# refactor\(web\): ComposerControlsBar renders without a memo\(\) wrapper · PR \#23093 · pingdotgg/t3code

[View on GitCafe](https://git.cafe/pingdotgg/t3code/pull/23093)

Repository: [pingdotgg/t3code](https://git.cafe/pingdotgg/t3code)

Visibility: public

State: merged

Source repository: pingdotgg/t3code

Source branch: refactor/split3-chatview-controls-bar

Target branch: main

Head commit: 4d5d85a12e0d632a56dacb4849a956d4ec1d87b8

[Discussion and reviews](https://git.cafe/pingdotgg/t3code/pull/23093)

[Commits](https://git.cafe/pingdotgg/t3code/pull/23093/commits?format=markdown)

[Files changed](https://git.cafe/pingdotgg/t3code/pull/23093/diffs?format=markdown)

## Description

---

`ComposerControlsBar` was wrapped in `memo()` in #23058. apps/web compiles with the React Compiler and has no manual memo anywhere else, so the wrapper is the odd one out.

This drops it. The compiler already caches the `<ComposerControlsBar …/>` element in `ChatComposer`: every prop passed is either a cached value or a stable callback, so when the props are unchanged the parent hands React the same element and the subtree bails out, just as memo did. No parent change was needed.

Renders (total committed fibers, Codex model, server thread, median of 3):

| Interaction | with memo | without memo |
| --- | --- | --- |
| Type 20 chars | 167 | 154 |
| Type 20 chars with an image attached | 122 | 122 |
| Open the slash menu | 444 | 431 |
| Traits Medium <-> High | 281 | 281 |

`ComposerControlsBar`, `ComposerModelPicker` and `TraitsPicker` render 0 times while typing in both columns. The small drops are sidebar tooltip noise, not this change.

Tested:
- apps/web typecheck, lint on the touched file.
- React Compiler coverage test for `ComposerControlsBar.tsx` and `ChatComposer.tsx`: 0 bailouts.
- Hands-on in a dev build: model picker opens with its list, the runtime mode combobox lists its 4 modes, traits flip between Medium and High, typing with an image attached.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

