I have yet to see a chat interface on iOS meet the quality bar set by the Messages app
- interactive dismiss
- keyboard gesture that starts when your finger touches the search input
- uses content inset so you can see the keyboard blur effect
13 3 63I was going to say “in react native” but actually nobody has done it! even the good ones like whatsapp don’t do the content inset part
1 11the problem with react native in particular is that the flatlist `inverted` prop sucks and is basically unusable if you want your list to be accessible. so we end up relying on some pretty hacky behaviour to keep it scrolled to the bottom
would love to revisit (maybe when we do groups???)
3 12trying to publish this as an npm package but they're not letting me have the name `expo-download-more-ram` :(
@samuel.bsky.team/expo-download-more-ram
config plugin for requesting increased memory limits
tangled.sh
they don’t want you to know this but you can literally download more RAM with an @expo.dev config plugin
https://github.com/bluesky-social/social-app/blob/main/plugins/withAndroidManifestLargeHeapPlugin.js
github.com
Bluesky’s social-app doesn’t use any global state manager (redux/zustand/jotai/mobx etc). Why is that? 🧵
an elaboration on this post:
the problem I have is that it changes global state from a last resort to a first resort. thus the lowest effort solution always turns into a nightmare mess instead of being isolated and composable
What we do use:
- plain old React context
- @tanstack.com query
Having used React context at scale… I have to say the react team was cooking once again. Yet another case of weird ergonomics pushing you to work in a good way.
Hoisting state to context being a bit of a PITA is a feature, not a bug!
1 20Adding more and more to an enormous app means by and large, stuff gets implemented in the lowest friction way. This is where composition shines. You want state to be as local as humanly possible, so it doesn’t get everywhere.
1 14Global state managers on the other hand have the opposite effect. The lowest friction path becomes making your stuff global. This does not scale well at all, and becomes increasingly incomprehensible.
1 15The key with using Context correctly is to only put one thing in them at a time. Got two things? Use two contexts. The danger zone is when you start putting large bundles of stuff in there, like you would a global state manager. This is obviously gonna make your whole app rerender.
2 16My heuristic is to only bundle stuff into an object when it’s stuff that isn’t gonna change: functions, for example. We have a useNonReactiveCallback hook which is great for this. This means you’re not gonna cause a rerender.
1 8Then if you’ve got values that might change, put em in their own context. This means they won’t trigger rerenders of anything that doesn’t need them.
I messed this up recently: the controls that opens the dialogs has the functions in an object from context. The mistake was I got lazy and needed…
1 6to also pass down an internal value to another component, so I stuck it in the same object. This value changes every time you open a dialog, so even though it’s only *used* in one place it gets *consumed* in many many places, triggering unnecessary renders. This is such an easy fix: just move it out
1 6Conclusion: react context is good actually and pushes you towards good code. You just need a bit of hygiene when using them: mostly just avoid bundling stuff together!
pro tip: add a displayName to your contexts so you can tell wtf is happening in your profiler
2 1 26is it a footgun? sorta. but with react context, it's usually a case of "you're holding it wrong". with global state managers, it's impossible to *not* hold it wrong. don't make stuff global!
3 16they don’t want you to know this but you can literally download more RAM with an @expo.dev config plugin
https://github.com/bluesky-social/social-app/blob/main/plugins/withAndroidManifestLargeHeapPlugin.js
github.com
translation button on Android works again!
📢 1.106.0 is rolling out with various bug fixes and performance improvements. Users will also be notified of an update to our Community Guidelines and other policies.
Learn more about these changes in our blog post: bsky.social/about/blog/0...
Updated Terms and Policies - Bluesky
We’re updating the language in our terms and policies to better explain our approach and provide more detail.
bsky.social
been trying to persuade the algo team to add a Poison meter to Discover but they don't seem to want to go for it
so hyped!!
Integrate Sonner for toasts by estrattonbailey · Pull Request #8839 · bluesky-social/social-app
Integrates sonner and sonner-native for our toasts.
CleanShot.2025-08-13.at.15.27.35.mp4
Android looks exactly the same. Real W for this library tbh.
...
github.com
ooh this is fun release! faster ios builds is huge! and predictive back gesture is exciting
We are excited to announce the release of React Native 0.81! 🎉
This new version brings Android 16 support, faster iOS builds (experimental), and several bugfixes.
reactnative.dev/blog/2025/08...
React Native 0.81 - Android 16 support, faster iOS builds, and more · React Native
Today we are excited to release React Native 0.81!
reactnative.dev
oooh and of course my most anticipated change:
allowSwipeDismissal on Modal
fiiiinally the bsky post composer can be dismissed smoothly!!
iOS26 Beta 6 app open/close animation is actually so fire. they’re cooking with this one
2 1 30@tangled.sh dares to ask the question: what if github didn't take 10 seconds to load every time you click anything
1 16 150@gork does git blame have a statute of limitations
good news: massive perf win found
bad news: it was my code that made it slow in the first place