You could think of it as using React Native Web (RNW), but better. Tamagui is using a trimmed down version of it called react-native-web-lite which is trimmed for bundle size and perfomance: https://www.npmjs.com/package/react-native-web-lite
RNW was independent of styled components, but you could use them together.
The site’s crashing on iOS Safari before loading finishes (client site exception), so I can’t see the contents. The library doesn’t look too good so far…
React seems less than 2x slower than painfully optimized vanilla code in js-framework-benchmark, even considering the "swap rows" test, which is not that important but where React does terribly in. https://krausest.github.io/js-framework-benchmark/current.ht...
It’s anywhere from 2-10x faster than a “universal” aka shared-code app that today would use React Native + React Native Web. It’s about 2x better render time over something like emotion or styled components as well when it does flattening, which is a good amount of the time, plus faster at startup etc.
Basically it’s hard to be fully precise, but if anything 2x rounds down in the big picture.
I'd like to see how it performs in js-framework-benchmark. That it's faster than emotion or styled-components don't really mean anything when comparing the frameworks themselves, and much faster css-in-js solutions can be written for any framework basically.
There’s benchmarks and code example both on this post and on the rest of the site showing this, the tree flattening is novel and what really makes a huge difference. On the site homepage it fully removes over 600 components from having to render at all.
Thanks for the link, interesting. I'd still recommend making a submission for js-framework-benchmark, otherwise it's kinda like preact signals, where the performance aspect of them is kind of a marketing aspect really, and they don't actually improve the score much at all in js-framework-benchmark, hence, presumably, why they haven't submitted an implementation yet. The more data the fewer doubts.
The standard benchmark mentioned (krausest) is for JS frameworks. But Tamagui is not a framework. (It uses React as the framework on web, so would have similar perfomance to that in krausest.)
Tamagui is a style and component library (plus optimizing compiler). Do you know of any standard benchmarks for any of those?
Ok, but then I don't understand the claim that it's faster than React while using React. I don't know of any more specific and good benchmarks for that.
Oh, that’s just mostly (afaik) the result of the tree flattening it does being an optimization of React, because it gives React less to handle in the first place. That’s why benchmarking framework render operations like krausest does doesn’t really apply. Because it is a nano benchmark of individual operations on the tree, not the size of it. You’d need a macro benchmark on a real world app to measure gains from reducing the DOM tree size. That would be very app-specific, and so the gains from that would also be very specific to how the app was designed. The closest you could get (that I’ve seen) is these micro benchmarks on a small custom DOM tree: https://tamagui.dev/docs/intro/benchmarks
> There’s benchmarks and code example both on this post and on the rest of the site showing this (...)
I feel this sort of approach lacks honesty and fails to be objective. Anyone can cherry-pick a customized test where their stuff comes out as the best of class, no matter how underperforming it is.
To have a proper apples-to-apples comparison, standard benchmarks are the way to go. Everything else sounds like snake oil and hand-waving.
> Not really. Just put together a benchmark and let it speak for itself.
You seem a little bit split on this one :) Yes, creating a fair benchmark is hard. Yes, it's hard to get other people to evaluate their things using your benchmark. Yes, it's hard to do an apples-to-apples comparison.
Not really. By "putting up a benchmark" I mean an objective and verifiable standard set of performance tests that everyone interested can contribute their best effort.
I means nothing if you roll out a cherry-picked ad-hoc test that compares a corner case of your best effort to a half-assed underperforming implementation of a competitor you chose because it suits you best.
There are standard benchmarks out there, which were already mentioned in this discussion. It takes virtually no effort to roll out Tamagui's best effort. Not using those actually requires more effort than using them, which casts doubt over the validity of self-serving cherry-picked ad-hoc tests.
The benchmarks are open source and adopted from competitor libraries, standard tests that style libraries have used for a long time. Nothing deceptive.
The other benchmark posted tests more framework level stuff, but could be repurposed to show a more “typical app screen” with some effort.
The standard benchmark mentioned (krausest) is for JS frameworks. But Tamagui is not a framework. (It uses React as the framework on web, so would have similar perfomance to that in krausest.)
Tamagui is a style and component library (plus optimizing compiler). Do you know of any standard benchmarks for any of those?
There's no such thing as a standard benchmark, but I benchmarked 8 different setups using benchmark source from two competitor libraries. If you have a better idea let me know.
In the ideal you'd have to benchmark a heavy screen that you'd have to write for every competitor, and then provide timings across many different facets - initial load, runtime, total time, window resize, etc. As far as I know no one does that for anything, even backend stuff as it's just too much effort (even the TechEmpower benchmarks are micro and not like this).
If anything though Tamagui will look even better there. I've open sourced the results, re-used benchmarks from rival libraries, shown my work, and even published the 3 benchmarks that don't do as well for Tamagui. It's as Apples-to-Apples as it gets and it's not measuring anything weird this is straightforward stuff.
Almost but not quite true same. Rendering a typical app screen is probably the “right” ACID test, this is testing something very different - insert/remove row etc.
I’d love to make a benchmark someday despite my bias, maybe just a profile page or feed or something generic, and could have side tests for animations, theme changes, responsive styles, and logical styles. Those are the key areas for a style library. Tamagui is actually 10x or more at a few of them.
I think he meant there’s no standardized benchmark for styling and component libraries, or optimizing compilers, all of which Tamagui are. (Tamagui isn’t a framework, so wouldn’t fit into krausest benchmark, as you know).
I had given up on universal apps before finding tamagui. We’re rebuilding our app experience with this now and seeing the optimizing compiler work is beautiful. Native feels speedy, and the flattened classes it produces for web makes the experience feel first class. SSR friendly to boot.
A little off-topic, but having used Raycast a little on a mac, I have to say that I wish there was react-native on Linux. It seems likes the react-native desktop project is maintained by microsoft, so there is no incentive for them to port this to linux, but what would it take to do that? Does anyone know? It seems to hinge on GTK and QT being hard to integrate with.
The problem with porting gui libs to Linux is - what is "Linux GUI"? Likely you would want to port it to either Qt or GTK; other routes might be a bigger lift.
Fwiw, React Native for Windows targets WinUI & for macOS targets UIKit (though Microsoft's work here builds a lot on Facebook's work targeting iOS).
A TUI target for React-Native would be nice, but Ink gets pretty close (it builds on Facebook's Yoga lib to provide React terminal components - it's not a full "menu/window/view managing" type TUI lib but Yoga is the CSS Flexbox re-implementation behind React-Native, so building a layout is pretty straightforward).
I personally don't think this is "the problem". Every platform has more than one UI library: on macOS you have AppKit, UIKit and SwiftUI. Windows seems like the worst offender with WinUI, WinForms, WPF, Blazor, .NET MAUI, etc [1].
I do think it's just a incentive issue. Supporting a platform on React Native takes plenty of effort, so without a big app as both the motivation and test-bed figuring this out there's little reason to invest in it.
Every platform has more than one UI library but there's two (closely related) fundamental differences:
1) there's typically just one canonically recommended for a given use case at a given time
2) they tend to a better job interoperating with one another & conforming to a consistent desktop paradigm than popular Linux equivalents (see e.g. running qt apps under gnome)
This is all largely because they come from singular entities - achieving the above would require more effort & coordination from Linux folk (though KDE do a decent attempt - Gnome has a lot to answer for here).
They have the same incentive as with supporting mac with react-native-macos, more platforms to push their services onto. The limitation seems to be technical, as other react-native on QT projects seem to have been all abandoned (Valence Native being the big one mentioned on react-native docs).
I feel like, in the last few years, we're making huge progress towards being able to easily build performant, cross-platform UIs with great dev ergonomics and minimal code, yet we're not quite there yet, despite web development existing for decades.
Every time I try one of those new shiny things it always looks great at first, but then when "hello world" meets the real world you always hit some wall (be it routing, SSR, styling, state management, data fetching, performance, etc), beyond which things can get pretty messy. I've never seen a real UI codebase that actually looks good.
I wish we could finally get there. Maybe WASM will help shake things up a bit.
This sums up my feelings about the js ecosystem entirely. Lots of growing pains.
I've felt for a long time that every industry shift on the long road from simple server-side rendered monoliths to client-side heavy js SPAs we have taken a step forward in what is possible while taking multiple steps back in so many other dimensions (simplicity, security, dx, etc.) I think by the end we will be in a better place across all of these but it feels like we have been crawling out of a hole we dug ourselves to get there.
Sadly, I don't share your optimism. If the current state of JS isn't proof enough that it is doomed to be forever reinventing itself I don't know what is. Layer upon layer is a recipe for disaster which soon becomes apparent with these new toys once you require more than "Hello Word". I'd rather be saddled with Spring Boot than have to wade through the quagmire of current JS frameworks.
Expo - Handles app routing of screens
Next.js - Handles web routing of screens (SSR Works)
React Query - Handles data fetching and hooks (Expo + Next)
(Others are using TRPC with clients in Expo and Next)
Zustand - Handles gllobal state (Expo + Next)
Tamagui - Component libary (Expo + Next)
Performance on the web with SSR rendering, React-Query pre-caching, and Next.js static builds is insanely good.
You have to bring your data fetching, and state, but `create-tamagui-app` is pretty amazing if you get stuck into it for a couple of hours.
I imagine in a few months there will be a monorepo starter with:
Expo
Next
Prisma / Supabase auth and database
Data fetching with TRPC
Tamagui Design System
Zustand client-state
Looks interesting. It looks to be under MIT license (great) but the landing page doesn’t mention that. You might as well maximize the benefit of open-sourcing the code by claiming that on the landing page. (It’s true that most anyone actually interested will go look [as I did], so not that big a deal perhaps.)
This looks very interesting. I still question whether teams need this or React Native when they could just bring their existing React web app to mobile with Capacitor. The benefit to that approach is being able to use React web frameworks like Next or Tailwind, without having to use a system specifically designed for native mobile or React Native. Regardless, different solutions work for different teams and this looks like a very interesting project that I need to spend some time with.
This is still such a problem - as a small startup we still have two completely separate code bases that we need to maintain with a tiny team (though we share Redux and Tailwind thanks to https://www.npmjs.com/package/twrnc). If we could "flutterize" our apps and make them run everywhere like this lib allows us to that'd save a huge amount of time.
I've never done mobile, but I'm learning so much here. Thank you everyone!
We need to launch a mobile app because someone started impersonating our web app and abusing our API. Their Google Play app has 100k+ installs, and it's rapidly growing. They're giving us a bad name too by injecting ads and degrading performance.
We have a React/TypeScript app (in a monorepo if that matters) and need to launch something on Android to get rid of these copycats.
I do not think it’s that straightforward actually. WebViews are JIT compiled which leads to big performance gains. React Native only can use a JIT with Hermes and Hermes is just plain worse than something like V8 with JIT enabled.
I don’t think RN can use a JIT at all on iOS. Only WKWebView processes can due to Apple’s security model. This makes Capacitor JS significantly faster for certain workloads
You should try to communicate more forthcomingly that CapacitorJS bundles the webapp with the native binaries, which means that you get better startup performance, but at the cost of not being able to serve the webapp fresh from the web (instead having to go through app store review process on every update like with native apps).
I used Tamagui to build a number of screens for a new product we're working on, and I saw 90+ lighthouse scores on every page. The fact that I can get that, with SSR support, inline styles, psuedo selectors, typed themes, and that it works on iOS and Android is novel.
I built the first library for React Native that supported Web/responsive design (Dripsy), so it's cool for me to see Tamagui taking this idea to the extreme.
Tamagui basically solves the part of styling + rendering UI. It works on both web and native.
As for logic/data fetching...this has gotten far, far better in React over the past few years.
For data fetching, assuming you're using REST, @tanstack/react-query is incredible. It gives you a "hook" to wrap any async function, and returns loading states, errors, etc.
In the past, people used Redux, but it's out of fashion now. I prefer a library called zustand whenever I need non-data related global state management.
Tamagui for "View" components and styling (+SSR on web)
+ React Query for data fetching, cache management, and neat hooks to use that data in apps. (+SSR on web
+ Zustand - "lite" state management on RN and React Web
+ Moti for X-Platform animations
+ Zeego for X-Platform menus
= Ridiculously high percentage of code re-use across web and react-native apps.
I would definitely disagree with "Redux is out of fashion". Redux is still by far the most widely used state management lib with React apps, by a very large margin - my estimates are that 35-40% of React apps use Redux, and no other state management lib appears to be over 10% [0].
We also get a lot of very positive feedback on our modern Redux Toolkit package, which we designed to simplify Redux usage [1], and it includes our "RTK Query" data fetching and caching API as well [2], which is similar to React Query in use case and API.
Mostly things that are very widely used in industry are indeed no longer “in fashion”. Instead they were in fashion and actually proved valuable enough to have staying power (as opposed to most fashionable things that are junk). Charitably, anyway — sometimes it seems you can’t tell why something is still widely used.
Probably the mentioned hooks-based approaches are indeed fashionable now. Remains to be seen whether they’ll stick around.
My team at work has completely rewritten from Redux with Redux Form to Tanstack query and React Hook Form over the past two years, and we don’t miss a single thing about Redux.
We make an app that contacts lots of microservices in sequence and combines the data in many ways. Having automatic refetching, caching and the like by default makes a world of difference.
I don't know if it's still the case but when I started my career (granted, some decades ago) using the new hotness X/Motif + C++, there were still more lines of COBOL around than anything else. (Hell, might not have been the case then, but that was the yarn.)
RTK Query is an excellent package! Coming from the React Query world, I inherited an RTK Query project and was initially disappointed, but have come to prefer it over (the also excellent) React Query.
I’m not particularly interested in the cross-platform/React aspects of this (although they’re impressive too!). But I’m quite interested in the way it optimizes styles! I hacked something similar together with Fela and an early partial hydration solution, emphasis on hacked. And the DX of my solution is great… until there are a lot of styles, and then builds slow to a crawl. I’m looking forward to giving this a try, and digging into the source to see how it’s done.
I don't know how in the world anyone can claim "2x performance" when clicking on a navigation element, saying out loud "one Mississippi, two Mississippi" and then having the content show up counts as "performance"
Want to see something else neat? Open the dev-tools and just wave your cursor over the navigation elements and watch the browser spray GET requests to some json files. I guess they made it Cloudflare's problem, but ... I'm glad I didn't try to view this on mobile
This is a demo blog post that loads every demo across the site, so it won’t be light.
Making claims like this is like claiming SpaceX can’t go to space because their lobby isn’t aerodynamic.
Also the prefetching is Next.js standard practice, not only does it have nothing to do with Tamagui but it’s is good for performance.
The homepage gets excellent lighthouse scores despite being an order of magnitude more complex than your average app due to showing off every feature in the library.
It was my understanding that the site itself was written in the framework, so if I have that experience while reading the docs, it's not a great selling point, right?
I can see we just have different expectations for a website, so I wish you all the best with your project
There’s a difference between a blog post showing off every feature of something vs the thing itself in practice - but even then, I think you’re wrong. Even this super long blog post showing much more than your average app/site would is fast and has a >80 Lighthouse score.
If you want to dispute the performance claims please do! But don’t spread FUD. You mis-construed prefetching for some sort of accidental performance mis-step when it’s the opposite and improves performance, without seeming to even realize what it is.
Anyone here develop apps with something like capacitor? Their ionic appflow seems like a closed in ci/CD when we could do so in github. Any alternatives? Foss?
Reading the docs, there seems to be a large amount of magical component creation going on that I find difficult to read. A key benefit of React is the simplicity of a component accepting props and using them in its render function. This library seems to dynamically create a component with a custom configuration language such that it requires a lot of thought to understand what is actually going on. It defines newly available props and their usage differently to other React components, reducing readability considerably.
Of course a person can get used to these things, but I question whether it scales to non-tiny teams. There’s a real smell of ye olde dynamic class creation here which React moved away from for very good reasons
There’s nothing at all magical, I’m not sure what you’re thinking is exactly. That’s actually a huge benefit of Tamagui over something like Tailwind for example. You just pass in props and use props just like normal.
If you’re talking about the styled() helper, that is something many React style libraries have standardized on from Emotion to Styled Components to Stitches. And actually it’s very important for an optimizing compiler because it limits you down to a statically analyzable subset that focuses just on styles. There’s no magic there either - React Native itself has a similar API with StyleSheet.create, except it won’t optimize even with a future compiler when you start nesting multiple things. That’s where styled() shines.
It's always a surprise to see comment like yours - it's obvious that there is a huge gap in how each developer circle sees complexity. In the examples, you need to use the provided Stack component, special props like $gtSm, theme values like $2, the styled() function, variants, and then stuff like useMediaPropsActive() if you want to build your own components. That's plenty of magic.
The exact same conversations were had when JSX came along, react-native-web, etc. We just keep on piling up more and more abstractions.
What is "magic" about any of those? React components are functions, so `styled` would be a function that returns a function. The "special props" are just arguments to those functions. If these are all documented, where's the magic?
What’s funny is I see too much API surface complexity everywhere - a big part of the reason Tamagui exists! For example the entire suite of web specs is insane and never ending, with CSS growing by the day.
Some replies: you don’t have to use a special stack you can pass in any component. Theme values and media props are definitely a bit of sugar but hardly magic - they map 1 to 1 to CSS and the other most popular style libraries. And writing them any other way (cross platform) simply doesn’t exist or is much much more complex, so I see them as both necessary and incredibly easy to understand coming from CSS.
The styled function is the whole point! That’s the whole library so that can’t really go away, and it’s just a plain old function there’s 0 magic there.
useMediaPropsActive is a utility function exported for very advanced use cases and it says as much in the docs.
I’ll give you variants, those are borrowed from Stitches and other libraries. They solve several problems elegantly and are also easy to understand. If there’s only one new thing to learn with something as complex as a style library, I’ll take that. Especially with how nice variants are.
I understand where you're coming from, but no, these are not plain functions. This is an optimizing compiler. How long do you think it would take you to read and start understanding how it works: https://github.com/tamagui/tamagui/tree/master/packages
No disagreeing that it can be a nice experience using a system like this where things "just work" if you stay within their boundaries; but there is no denying the sheer complexity of it. It is absolutely magic vs say, a bit of HTML + CSS - in which case you can consider what's going on inside the browser as magic.
I’d agree with you if the compiler was mandatory, but it’s not. In fact the docs recommend not setting it up until you are ready to deploy to production. It very much is just a function.
As a former JS-head and newly-Flutter/Dart-head, this is certainly a step forward for JS frameworks.
However, one thing notably absent from the page and a quick Google search are layout animations. React-Native has this in the (poorly-supported and almost-niche) form of LayoutAnimation, however support is notably missing in React-Native-Web and other frameworks attempting to bring true cross-platform support.
As for me (not that anyone cares), this is a very cool advancement, but doesn't change many of the complaints against the current (and numerous) set of issues with JS, and will be sticking with Flutter.
I feel this is mostly a good display of the confusion around what the heck is even doing what at this point. You can count me in this camp. And I am terribly interested to know.
Weird I get some reports of this but very rare. I’ve tested now in iOS 15, 16 and desktop across a bunch of devices. Can’t replicate with me or close friends. I’ll download chrome for iOS.
So many things try to sell me on speed. That’s nice but the developer experience and debugging, examples and documentation is what sells me on a thing.
It has a ton of DX features that I think are underrated: both the debug prop and pragma, and compile time data-attributes to help link your files to DOM.
Tamagui seems to hype performance but it seems like it’s adds a lot of complexity to optimize web styles which are already very fast. The difference when talking about native (not react-native on web) is tiny IIRC
The great thing about it is that it basically gives you the benefits of CSS-in-JS on the web, but without the downsides, since it compiles away to atomic CSS (even ternaries!).
It’s true that it’s marginally less performant than vanilla React Native (within 10%, looks like 1.9%):
And for that tiny difference on native, you in return get close to 100% code sharing between native and web. As opposed to writing vanilla React Native and then writing it again for vanilla React.
you get very similar code sharing with react-native-web and StyleSheet.create…
I guess i am just much more interested in making the native side faster. I have never had issues making something in React Native and then having the web side be the slow part.
Web is the much more performance sensitive side, where it improves most.
If you do pseudo styles or responsive styles with RNW your web app will absolutely tank in all metrics, runtime/lighthouse/load/layout. Tamagui fixes all four. That normally prevents code share for anything more than small apps or totally performance insensitive use cases, otherwise Tamagui makes a big difference.
144 comments
[ 5.3 ms ] story [ 201 ms ] threadRNW was independent of styled components, but you could use them together.
Edit: Glad I'm not a web developer.. good luck dudes, haha.
I'm running iOS 16.2 (20C65) FWIW
“ Application error: a client-side exception has occurred (see the browser console for more information).”
React seems less than 2x slower than painfully optimized vanilla code in js-framework-benchmark, even considering the "swap rows" test, which is not that important but where React does terribly in. https://krausest.github.io/js-framework-benchmark/current.ht...
Basically it’s hard to be fully precise, but if anything 2x rounds down in the big picture.
https://tamagui.dev/docs/intro/benchmarks
Tamagui is a style and component library (plus optimizing compiler). Do you know of any standard benchmarks for any of those?
I feel this sort of approach lacks honesty and fails to be objective. Anyone can cherry-pick a customized test where their stuff comes out as the best of class, no matter how underperforming it is.
To have a proper apples-to-apples comparison, standard benchmarks are the way to go. Everything else sounds like snake oil and hand-waving.
>> Basically it’s hard to be fully precise, (...)
> Not really. Just put together a benchmark and let it speak for itself.
You seem a little bit split on this one :) Yes, creating a fair benchmark is hard. Yes, it's hard to get other people to evaluate their things using your benchmark. Yes, it's hard to do an apples-to-apples comparison.
Not really. By "putting up a benchmark" I mean an objective and verifiable standard set of performance tests that everyone interested can contribute their best effort.
I means nothing if you roll out a cherry-picked ad-hoc test that compares a corner case of your best effort to a half-assed underperforming implementation of a competitor you chose because it suits you best.
There are standard benchmarks out there, which were already mentioned in this discussion. It takes virtually no effort to roll out Tamagui's best effort. Not using those actually requires more effort than using them, which casts doubt over the validity of self-serving cherry-picked ad-hoc tests.
The other benchmark posted tests more framework level stuff, but could be repurposed to show a more “typical app screen” with some effort.
Tamagui is a style and component library (plus optimizing compiler). Do you know of any standard benchmarks for any of those?
In the ideal you'd have to benchmark a heavy screen that you'd have to write for every competitor, and then provide timings across many different facets - initial load, runtime, total time, window resize, etc. As far as I know no one does that for anything, even backend stuff as it's just too much effort (even the TechEmpower benchmarks are micro and not like this).
If anything though Tamagui will look even better there. I've open sourced the results, re-used benchmarks from rival libraries, shown my work, and even published the 3 benchmarks that don't do as well for Tamagui. It's as Apples-to-Apples as it gets and it's not measuring anything weird this is straightforward stuff.
There actually is for web frameworks https://github.com/krausest/js-framework-benchmark
I’d love to make a benchmark someday despite my bias, maybe just a profile page or feed or something generic, and could have side tests for animations, theme changes, responsive styles, and logical styles. Those are the key areas for a style library. Tamagui is actually 10x or more at a few of them.
Not really. Just put together a benchmark and let it speak for itself.
The benchmarks speak for themselves.
I don't see any screenshots, so I presume it's the entire site?
the entire site is also made with Tamagui, so the landing page uses a lot of it, and you can see visuals and code of all the components in the docs.
"<17kb, 0-dependency. Every React Native API, typed, without bloat on the web."
As far as I know there's no alternative for cross-platform styling and SSR.
Love the variants API and responsive styles for native too.
The problem with porting gui libs to Linux is - what is "Linux GUI"? Likely you would want to port it to either Qt or GTK; other routes might be a bigger lift.
Fwiw, React Native for Windows targets WinUI & for macOS targets UIKit (though Microsoft's work here builds a lot on Facebook's work targeting iOS).
ahem, CLI. anything else is just bumpers in the bowling alley gutters and training wheels on your bike. (I only partially jest)
I do think it's just a incentive issue. Supporting a platform on React Native takes plenty of effort, so without a big app as both the motivation and test-bed figuring this out there's little reason to invest in it.
[1]: Not really a reference, but just a thread with people's thoughts on this whole mess: https://www.reddit.com/r/csharp/comments/vc3e2l/winui_3_or_w...
1) there's typically just one canonically recommended for a given use case at a given time
2) they tend to a better job interoperating with one another & conforming to a consistent desktop paradigm than popular Linux equivalents (see e.g. running qt apps under gnome)
This is all largely because they come from singular entities - achieving the above would require more effort & coordination from Linux folk (though KDE do a decent attempt - Gnome has a lot to answer for here).
Every time I try one of those new shiny things it always looks great at first, but then when "hello world" meets the real world you always hit some wall (be it routing, SSR, styling, state management, data fetching, performance, etc), beyond which things can get pretty messy. I've never seen a real UI codebase that actually looks good.
I wish we could finally get there. Maybe WASM will help shake things up a bit.
Expo - Handles app routing of screens Next.js - Handles web routing of screens (SSR Works) React Query - Handles data fetching and hooks (Expo + Next) (Others are using TRPC with clients in Expo and Next) Zustand - Handles gllobal state (Expo + Next) Tamagui - Component libary (Expo + Next)
Performance on the web with SSR rendering, React-Query pre-caching, and Next.js static builds is insanely good.
You have to bring your data fetching, and state, but `create-tamagui-app` is pretty amazing if you get stuck into it for a couple of hours.
I imagine in a few months there will be a monorepo starter with:
Expo Next Prisma / Supabase auth and database Data fetching with TRPC Tamagui Design System Zustand client-state
Someone's probably working on it right now
In my experience, it rivals other web-only libraries, especially with the compiler.
This is still such a problem - as a small startup we still have two completely separate code bases that we need to maintain with a tiny team (though we share Redux and Tailwind thanks to https://www.npmjs.com/package/twrnc). If we could "flutterize" our apps and make them run everywhere like this lib allows us to that'd save a huge amount of time.
Wrote an essay about our current solution here: https://nikodunk.com/2022-05-10-the-tech-stack-for-maximum-e...
We need to launch a mobile app because someone started impersonating our web app and abusing our API. Their Google Play app has 100k+ installs, and it's rapidly growing. They're giving us a bad name too by injecting ads and degrading performance.
We have a React/TypeScript app (in a monorepo if that matters) and need to launch something on Android to get rid of these copycats.
Us: https://FakeYou.com
Not us: https://play.google.com/store/apps/details?id=com.headbreyz....
(NB: I'd love to contract or hire someone to do this, in case anyone on HN is interested.)
I built the first library for React Native that supported Web/responsive design (Dripsy), so it's cool for me to see Tamagui taking this idea to the extreme.
Those seem mostly non-reusable?
Tamagui basically solves the part of styling + rendering UI. It works on both web and native.
As for logic/data fetching...this has gotten far, far better in React over the past few years.
For data fetching, assuming you're using REST, @tanstack/react-query is incredible. It gives you a "hook" to wrap any async function, and returns loading states, errors, etc.
In the past, people used Redux, but it's out of fashion now. I prefer a library called zustand whenever I need non-data related global state management.
= Ridiculously high percentage of code re-use across web and react-native apps.
What a time to be alive!
We also get a lot of very positive feedback on our modern Redux Toolkit package, which we designed to simplify Redux usage [1], and it includes our "RTK Query" data fetching and caching API as well [2], which is similar to React Query in use case and API.
[0] https://blog.isquaredsoftware.com/2022/07/npm-package-market...
[1] https://redux.js.org/tutorials/essentials/part-2-app-structu...
[2] https://redux-toolkit.js.org/rtk-query/overview
Probably the mentioned hooks-based approaches are indeed fashionable now. Remains to be seen whether they’ll stick around.
We make an app that contacts lots of microservices in sequence and combines the data in many ways. Having automatic refetching, caching and the like by default makes a world of difference.
This is not fashion. It’s quality.
I don't know if it's still the case but when I started my career (granted, some decades ago) using the new hotness X/Motif + C++, there were still more lines of COBOL around than anything else. (Hell, might not have been the case then, but that was the yarn.)
The official «Tamagui + Solito + Next + Expo Monorepo» starter:
https://github.com/tamagui/tamagui/tree/master/starters/next...
Or the more recent version that builds on that and adds tRPC and authentication (with Clerk):
create-universal-app - https://github.com/chen-rn/CUA
Want to see something else neat? Open the dev-tools and just wave your cursor over the navigation elements and watch the browser spray GET requests to some json files. I guess they made it Cloudflare's problem, but ... I'm glad I didn't try to view this on mobile
Making claims like this is like claiming SpaceX can’t go to space because their lobby isn’t aerodynamic.
Also the prefetching is Next.js standard practice, not only does it have nothing to do with Tamagui but it’s is good for performance.
The homepage gets excellent lighthouse scores despite being an order of magnitude more complex than your average app due to showing off every feature in the library.
I can see we just have different expectations for a website, so I wish you all the best with your project
If you want to dispute the performance claims please do! But don’t spread FUD. You mis-construed prefetching for some sort of accidental performance mis-step when it’s the opposite and improves performance, without seeming to even realize what it is.
Of course a person can get used to these things, but I question whether it scales to non-tiny teams. There’s a real smell of ye olde dynamic class creation here which React moved away from for very good reasons
If you’re talking about the styled() helper, that is something many React style libraries have standardized on from Emotion to Styled Components to Stitches. And actually it’s very important for an optimizing compiler because it limits you down to a statically analyzable subset that focuses just on styles. There’s no magic there either - React Native itself has a similar API with StyleSheet.create, except it won’t optimize even with a future compiler when you start nesting multiple things. That’s where styled() shines.
The exact same conversations were had when JSX came along, react-native-web, etc. We just keep on piling up more and more abstractions.
Some replies: you don’t have to use a special stack you can pass in any component. Theme values and media props are definitely a bit of sugar but hardly magic - they map 1 to 1 to CSS and the other most popular style libraries. And writing them any other way (cross platform) simply doesn’t exist or is much much more complex, so I see them as both necessary and incredibly easy to understand coming from CSS.
The styled function is the whole point! That’s the whole library so that can’t really go away, and it’s just a plain old function there’s 0 magic there.
useMediaPropsActive is a utility function exported for very advanced use cases and it says as much in the docs.
I’ll give you variants, those are borrowed from Stitches and other libraries. They solve several problems elegantly and are also easy to understand. If there’s only one new thing to learn with something as complex as a style library, I’ll take that. Especially with how nice variants are.
No disagreeing that it can be a nice experience using a system like this where things "just work" if you stay within their boundaries; but there is no denying the sheer complexity of it. It is absolutely magic vs say, a bit of HTML + CSS - in which case you can consider what's going on inside the browser as magic.
However, one thing notably absent from the page and a quick Google search are layout animations. React-Native has this in the (poorly-supported and almost-niche) form of LayoutAnimation, however support is notably missing in React-Native-Web and other frameworks attempting to bring true cross-platform support.
As for me (not that anyone cares), this is a very cool advancement, but doesn't change many of the complaints against the current (and numerous) set of issues with JS, and will be sticking with Flutter.
https://github.com/tamagui/tamagui/tree/master/starters/next...
It’s true that it’s marginally less performant than vanilla React Native (within 10%, looks like 1.9%):
https://tamagui.dev/docs/intro/benchmarks
But that is actually no small feat for a native component library, see f.ex. Nativebase’s longstanding unresolved performance issues:
https://github.com/GeekyAnts/NativeBase/issues/4302
And for that tiny difference on native, you in return get close to 100% code sharing between native and web. As opposed to writing vanilla React Native and then writing it again for vanilla React.
I guess i am just much more interested in making the native side faster. I have never had issues making something in React Native and then having the web side be the slow part.
If you do pseudo styles or responsive styles with RNW your web app will absolutely tank in all metrics, runtime/lighthouse/load/layout. Tamagui fixes all four. That normally prevents code share for anything more than small apps or totally performance insensitive use cases, otherwise Tamagui makes a big difference.