One is a React framework that does two things differently in hopes of simplifying how we build websites and apps:
1. It unifies React Native and React web with typed file system routing by making Vite able to serve RN. This lets you share (or diverge) your code in a simpler way for cross-platform apps.
2. We've partnered with Zero (https://zerosync.dev) to make local-first work well. We've been building a solution in One that makes Zero supporting server rendering, without waterfalls, and with seamless server/client handoff.
---
Honestly - I'm a bit hesitant to post One here.
HN has really soured on frontend/frameworks. And I get it. We've collectively complicated the hell out of things.
That's why I decided to build One. I loved Rails, it made me as a young developer able to finally realize way more ambitious projects than I'd ever done before. I also liked the promise (not implementation) of Meteor - it felt like the clear future, I guess just a bit too early (and a bit too scope-creeped).
I worked at Uniswap and built Tamagui and so spent a lot of time building cross-platform apps that share code. Uniswap is built on Tamagui and I think proves you can make really high quality UX while sharing a lot of code - but it's insanely hard and requires a huge team. My goal with One is to make what is now possible but hard dramatically easier.
And I think the path to there goes through local-first, because it makes building super responsive apps much, much simpler, and Zero is the first library to actually pull it off in a way that doesn't bloat your bundle or have very limiting constraints.
I happened to live down the street from Aaron, one of the founders of Zero, in our tiny town in Hawaii. We talked a lot about Zero over the last couple years, and I found it really admirable how he consistently chose the "harder but better" path in building it. It really shaped into something incredible, and that convinced me to actually launch One, which at the time was more of an experiment.
I can see a lot of potential criticism - do we need yet another framework, this is too shiny and vaporware-y, this is just more complexity and abstraction, etc. Happy to respond to those comments if they come.
I'm just building out something that I've been wanting for a long time. Opinionated enough to let me move fast like Rails, but leaning on the great work of team Zero so that we don't end up with the scope creep of Meteor. And honestly, it's just really fun to hack on.
In the end, after all that journey, I settled into Laravel Backend and Vue3. Every app I create now is just a copy-and-paste of what I've done before. The tech stack disappears into the background and I try to actually build the features that I want to build.
I'm definitely old because I see this great work called "one" and I look at the video and I get immediatey turned off by so many "new things". It's me - definitely me. It's maybe for a different generation of devs.
The problems themselves are way more interesting to me now. I get very upset when the tech gets in the way. I'll happily pay for licenses, fees, royalties, etc to clear the path.
It wasn't always this way though. The first decade of my career I didn't really care for the problems I was working on, so theorycrafting the tools all day was a nice respite. Coming up with principled clean architectures is a lot easier when you don't have to answer directly to the customer.
Doing stuff for actual customers is seen as grunt work. Their interests aren't ours, and we can't share what we learn with our peers.
So we end up reinventing the wheel just because it's more fun. And it is fun, and that's ok. Sometimes it's even useful. You just have to figure out what your real goal is, and not spend your whole life polishing your craft for its own sake.
You don't see the same bs in other areas of computer science.
It's not like databases haven't been reinvented every time there's a new fancy startup.
MySQL the OG "but web scale" DB (even with InnoDB because consistency level set to - you guessed it - "web scale"), then all the NoSQL kids because of course "web scale", then SSD/NAND write-amplification and LSM and LevelDB and whatnot and nowadays RocksDB. And there's the memcached/Redis/Valkey.
It's not like networking is not doing the same. HTTP2, HTTP3. DNS over HTTPS, how amazing it is to establish a TLS connection just to send a base64 encoded DNS question. WTF. And there's a myriad things in eBPF land, all the kubernetes-related CNI providers, and during the OpenStack years we had new overlay networks every year (VXLAN, Geneve, and I forgot the name of the other stuff), and if you go a bit closer to datacenter networking and peek into the firehose of 802.1 of new protocols you'll drown from the constant buzz over which variation of the same thing is the obviously best one! (I still remember when people started to realize that maybe there's a better and cheaper way to avoid VLAN and spanning tree problems than "just buy Cisco forever and don't forget to enable rapid STP (802.1w)" ... and then for a while there was MSTP (802.1s), TRILL, and SPB (802.1aq) and now it's managed networks all the way down, I guess)
I'm trying to work to ensure that doesn't happen to me. What I've realized is that I need to take breaks - of at least months or even years - and come back with fresh eyes to the things I know well.
And I need find new things to be a beginner at so that I don't forget what that's like. I'm trying and mostly failing to learn guitar over the past year. I've taken up resistance training in a semi-serious manner in the last few months, and that's going much better than the guitar.
It's 10× faster than in any modern approach, there's no build step, I can sync it to any server and it just runs, the code is simple, the end result is snappy, it loads immediately, it has great UX, and I don't need to scale to a million users anyway.
It's fast, it's secure, i implement everything myself -> it's flexible.
It's great that vite does the bundling, but it's the only job it does.
My page is now down to 2 ms response time, i don't see a reason to go back to the symfony/laravel days.
Simply put, stuff gets much more much quicker compared to 5, 10, 15 years ago.
Not being quite able to keep up with any and all frameworks popping up and being overloaded with the size and speed of current web ecosystem is a struggle for younger peers aswell, and the days of "you even COULD check out every other new framework" are long, long gone
Deleted Comment
Is it really an age thing or actually an experience thing? I see the same sentiment in a lot (though not all) of the replies here and I think the fatigue that people feel from announcements of new tools is really down to having seen the same promises of 'simpler' and 'better' before in hundreds of other tools, with none of them ever really playing out or lasting.
The simple answer as to why these tools don't last is that everything builds on and improves on everything else, but genuine 'improvement' is hard to quantify here and what we really have is changing abstractions, with the underlying contraints (browser environment) not changing as quickly due to the need for standardisation.
Web/cloud in particular is particular bad for churn in 'tools'. It seems surprising, as open source projects with no expectation for monetisation don't have a financial incentive to succeed, only the personal satisfaction of tool development and perhaps (cynically) a sort of online celebrity type of success that comes with being a known creator and maintainer of a well-used project.
For people that feel excited to learn new tools and techniques, when they stop feeling excited at this week's new shiny tool, I don't believe that's because the excitement of learning has gone, but the realisation that the new shiny is another thing operating at the same level of abstraction. Personally, new frameworks operating at the same level bores me, but deeping my understanding of the layers below is still exciting, and I personally think should have more emphasis on importance.
This doesn't mean people should feel discouraged from exploring new ideas and approaches, but it's important to realise that the cost to a creator of releasing anything into the web is virtually zero (essentially just development time), while the cost of adoption is high for every person that needs to learn yet another idea of how to structure their application and the abstractions that someone else came up with.
Web and cloud in particular seems to have a 'tools' problem, where every 'problem' that could be solved by simplifying or reducing (as general approaches) ends up just getting more tech 'solutions', but more tech to solve tech problems only serves to bury complexity.
Unfortunately it always ends up as the easier option to simply build new tools or build on top of what exists instead of developing a deeper understanding of the problem. It's also genuinely incredibly difficult to make sigificant changes to browsers as a target environment, so naturally all the tooling falls to things that can be done at development time or on-request.
Just my 2p.
I am so fed up of this churn. It is boring. It is uncreative. It is uninspiring. It is a waste of the limited time I have left it my life. All it achieves is to keep me shackled to the fucking hamster wheel and I am so tired of it.
I'm happy learn some new things even if there's resistance.
I really like vue. Laravel I don’t so much, but I appreciate how boring yet well designed it is.
I often wish the js ecosystem had real counterparts to laravel. We have too many ways to do things.
To whoever posted the video accelerated: don't do that. It's very difficult to understand what the man in the video says unless the YT speed is down to 0.75. What is the point of that ?
Don’t get me wrong, that’s super cool - but if you’re going to claim it’s local first software, I want to see the principles of local first software at play. And I don’t think Zero delivers that - at least as I understand it from its website.
Like, “the network is optional” and “the long now” and “you (the user) retains ultimate control”. It just looks like an excellent server sync system with client side caching. What if the data I need isn’t in the cache? What happens when I edit things offline then come online later? What happens if the company shuts down and the server gets turned off permanently? Will the app still work?
Local first software can handle these cases too.
[1] https://www.inkandswitch.com/local-first/
There is a lot of debate about this in the community. People like pvh, adam wiggins, and johannes have all said they consider Replicache and Zero part of the local-first movement [1] and that they would be sad if we and other things like us weren't in it. I was even invited to speak at local-first conf, where we announced Zero last May. [2]
I think in practice delivering on the local-first ideals is ultimately up to the app developer not the library. Like in practice every yjs app talks to its server over some bespoke protocol and is loaded over a URL. If that server goes away your yjs app is a brick. No less a brick than if your zero server goes away.
Similarly although everyone likes to claim Linear as a local-first app, if the Linear server goes away your Linear app is a brick. Yeah you can export the data from IDB or whatever but you could do the same for Zero or any of these systems.
That all said, for our part, we have recently tried to avoid claiming Zero and Replicache as local-first on our own sites to avoid this controversy [3].
I think we're building something really valuable that a lot of people are excited about. And I think we're making the right tradeoffs for the majority of software that most people use every day. So I don't really care too much if it qualifies as local-first (except insofar as I like hanging out with the local-first folks and would be sad to not get invited to the parties).
I forgot to mention this to Nate when he showed me these mocks for One because honestly almost everyone else (not us) refers to Replicache and Zero as local-first and it's easy to forget. I'll leave it to him to decide what to do with his own product, but it seems easy enough to me to soften the language.
[1] https://youtu.be/cgTIsTWoNkM?si=6bYAAunqd5kdl-UL&t=2692
[2] https://www.youtube.com/watch?v=rqOUgqsWvbw
[3] https://zerosync.dev/, https://replicache.dev/
I agree! I wanted live server sync like this for years. And I built ShareDB years ago along those lines, many years before the term “local first” came into being.
But I see a pretty big difference between “server based app with sync” and “local first software”, party invitations aside. I wish we made a term for server based sync - I think it’s marvellous, and it’s important for all sorts of use cases. I think it’s ridiculous modern databases don’t have live queries built in as a standard part of sql. You’re doing great work here.
But all that said, I personally actively avoid calling sharedb local first because I don’t think it is. One big difference is authentication - who has permission to edit the database? And when? With sharedb (and I assume zero), it’s possible to add logic on the server to reject edits. It’s not possible to do this in the same way when clients can write to Yjs or automerge, connect to one another directly and broadcast their changes without the server in the loop.
That’s a pretty big difference - at least to me. I can’t speak for pvh, since I don’t get invited to those parties. But I want language to differentiate those two kinds of software. I’ve been writing software that straddles that line for over a decade, and that difference of how authoritative the root server is really important. It really changes a lot of things about how we build software.
I think the situation is like if we didn’t have a good term for client-server encryption so everyone just calls their software E2E encrypted even when it’s just using tls and encrypting data in transit.
I don’t think you should stop going to local first events. But I don’t think being invited to super cool parties tells us anything about your code. That makes you, personally, a member of a community. But the local first software question is, as I see it, a technical distinction. Not a social one.
The zerosync website says this:
> But where Zero really shines is “local-first” style applications like Linear and Superhuman.
Personally, I find that a pretty confusing claim. “Seamless online / offline support”? Sure. Rad as f? Absolutely. Local first? Eeehhh. It looks like a modern sharedb with a Postgres backend, better caching, maybe cleaner client side api and no collaborative editing. Definitely cool, but very, very different how local first software is described in the paper. That or I should start claiming sharedb is local first too, and muddy the waters forever. Gmail offline mode? Local first everyone. You're welcome!
As for websites that support offline data but can’t be loaded without a server, why not? App manifests can solve a lot of that. (Though nobody ever tries actually opening websites when they’re offline, so maybe there’s no point setting it up).
Personally, I’ve never heard of Linear. And I’ve never heard “everyone say” it’s local first. But if it’s a brick without the server, sorry, but I think everyone is wrong.
Final note on the user-stuff: that's always up to the person writing the app anyway. You could make a "download the IndexedDB" button with a couple lines of code, but it's more than that, it's really a whole bunch of decisions you have to make as an app-developer to commit to it. And tbh I think the general understanding of local-first has settled on client-side + optimistic + offline - for the better.
That's not even close to what "local first software" means.
Can apps work without the server? Like, if the server goes down, will the app still work?
Can I collaboratively edit my data without the origin server? (Or at all?) Normally replication built on raw postgres queries relies on atomic row level locks on the server, while processing transactions. What happens if two people edit the same data at the same time?
Does it support end-to-end encryption, so my data isn't readable by the server at all?
Can I back up the app & my data together, and open it back up in 5 years and have the app still work?
All this stuff is talked about in the local first paper. Putting a sync engine in front of postgres (as described by the zerosync website) doesn't do any of this stuff. (Or maybe some of it? Its hard to tell without more information, and I can't find a link to the source code.)
It reminds me when Zoom advertised E2E encryption on zoom's website because the CTO clearly didn't know what "end to end encryption" actually means. It looks like an excellent product - so why exaggerate its capabilities?
"Local first" doesn't mean "edits are applied speculatively in the client before they hit the server". It also doesn't mean "caching part of the centralized postgres database in the client".
Go read the paper. The details matter. https://www.inkandswitch.com/local-first/
On the other hand, this is still tethered to the server, so likely more commercially viable than a true local-first design.
* Overall, not bad. Using React Native is far better than trying to mimic platform UI in the web, which is always terrible. * When tapping on an item on the “Feed”, the transition is made to the details _and then_ the navigation bar has a sudden title transition. This is weird. * The button in the upper left to switch between light and dark mode is nice but it should default to the system setting. It did not for me. * The Notifications tab content isn’t scrollable at all on my phone. Seems like a bug. * If you tap on an item in Notifications you navigate deeper in, but when you hit back you are back on the Feed tab.
Coming from native app development, it has the normal uncanny valley feeling that React Native gives off but for normal users they may not notice it as much.
How do you know?
It's just not a 20-something with the energy, nor interest, to be out every weekend til 2am
Because to me it just looks like another shiny thing that tries to be everything to everyone and ends up doing nothing good. They seem to be good salesmen, but less competent devs, at least when it comes to creating real innovation, not repacking old code/ideas.
I'm saying that because, both of their websites are so bad that they create problems in Chrome, something that is rather rare nowadays with an adblocker; the Tamagui one repeatedly eats memory and crash in tab and the One seem to have some rendering issues.
It did not investigate because I don't really care, but I'll say it doesn't inspire confidence at all and in my opinion, it is largely enough evidence to dismiss the whole thing as a toy project of semi competent devs.
In another comment, I have seen you drop the hypocrisy and be a bit mad about the support you gave for disappointing results. I think the one you are the maddest at is yourself, because you feel you should have known and to be honest, you probably should have. But we all learn everyday...
Our websites both get very high performance scores and if you profile them neither of them does anything at idle. Tamagui site does a ton of fun animations to show off how well it works, it's possible if you're on Linux or Windows with certain drivers causing issues, mind telling me any of that info?
I'm an old school web developer, I've spent a lot of time on performance. I'm proud of the sites, they weren't easy to pull off. I checked in Chrome again just now and things feel very smooth, and I don't see memory runaway. Do you have any other extensions?
Just to give a bit more meat to my comment: these experiences are really helpful when you're in the position to adopt a potential time-saving (stack-cutting/unifying) technology. I find I get a huge benefit from word-of-moth experiences from others who have tried such frameworks. Specifically compared to takes on the _idea_ of the technology.
So I don’t think it’s surprising if you have regressions when upgrading 200+ packages for any project, and I also don’t think you should upgrade it honestly more than once every six months.
Second point is that we also moved (and had to move) much faster than a typical project. Because we had so many packages and were solving very hard problems, we had a lot of ground to cover. We never broke any API surfaces in a minor or patch, but we weren’t afraid to improve our underlying code because if we didn’t, on a project of that scale, we’d have quickly succumb to tech debt. A good chunk of our UI kit was under the “beta” tag until recently.
That said I’ll take responsibility for it. I wonder when this was that you adopted it, I think we’ve gotten a lot better over time as things have stabilized. We stopped adding features over a year ago now, and have entirely focused on stability, performance and documentation since.
A final note is that I have never been full-time on Tamagui, it’s always been a side project of mine while I had a full time job. We have a large test suite, but again, the surface area of the project is simply massive.
Now that I am full time on One and Tamagui, I am looking forward to proving that we know what we’re doing. We’ve hired great developers and have greatly expanded testing even just in the last few months.
One is a lot simpler than Tamagui. Like… not 10x simpler, closer to 1000x simpler. I keep telling people: a universal framework is surprisingly simple compared to a universal style library + UI kit.
Editing to add one more point of context. One of the best and pickiest developers I know - Fernando Rojo - has been using Tamagui since the beginning. He even wrote his own style library before Tamagui. He recently started on a new side project that he wants to turn into a real venture down the road, and he is using Tamagui for it. It’s actually one of my most proud accomplishments. It’s an extremely strong signal imo, as someone who is known for NIH and being very picky to choose such a big dependency like Tamagui again.
Tamagui is impressive, but TBH it's sounding like this is a bug, not a feature.
> So I don’t think it’s surprising if you have regressions when upgrading 200+ packages for any project, and I also don’t think you should upgrade it honestly more than once every six months.
In my experience it gets exponentially harder to upgrade packages the longer you let them get out of date.
I first encountered Takeout about a year ago while experimenting with cross-platform development after reading this blog post: The Different Tech Strategies for Building a Cross-Platform App (https://magnemg.eu/the-different-tech-strategies-for-buildin...)
At work, we urgently needed an iOS app to enable push notifications for our logistics app, but our frontend was web-only and built with React/Next.js. Since the codebase was already several years old with many screens, we decided to port it to Capacitor, which led us to adopt a stack with Next.js and Capacitor (https://github.com/RobSchilderr/nextjs-native-starter).
However, once we began working with Capacitor, we ran into numerous issues. Dealing with the iOS keyboard and Safari WebView was almost impossible with famous scrolling issues, and Android’s Chrome WebView also suffered from poor performance (https://github.com/ionic-team/capacitor/discussions/3899).
This experience pushed me to switch to Expo with Solito and Tamagui, and the new stack has been a game changer. The support from Nate and the Tamagui team has been outstanding. Also Expo and EAS has been working flawlessly.
Now, with One, cross platform development is entering a new phase which address the final challenges of cross-platform development. Sharing code with Expo and Tamagui used to be manageable only for those familiar with cross-platform solutions, but now it’s becoming accessible to everyone. I bet it will be easier for new folks to understand how to work with Expo and Tamagui.
Combine that with local-first, and small teams will be able to build high-performance applications across three platforms using just one simple codebase quickly.
Tamagui Takeout is a paid fullstack starter kit based on Tamagui (and Drizzle): https://tamagui.dev/takeout
They’ve started a rewrite of Takeout to One (Zero instead of Drizzle, etc.), and are grandfathering in all existing users (also those who start using it before the rewrite is released). More in thread:
https://x.com/tamagui_js/status/1841985327139098649
PS: I’m happy you found use of my blog post about the various tech strategies/choices when making a cross-platform app. :)
And thanks for adding the context on Takeout.
more context: https://www.youtube.com/watch?v=aWfYxg-Ypm4
And the solution, of course, is a framework on top of a framework on top of JS and the DOM. OK, maybe I'm being too harsh.
1. Write lots of code to deal with the complicated problems
2. Use a framework that abstracts around these problems and solves some of them for you
3. Cut features from your app
This framework helps you with approach 2. If you don't want to use it, you are welcome to use approaches 1 or 3.
I do think that some UIs are more complex than they need to be.
Deleted Comment
Me and my team have been working on a new Web Draw-first IDE that we're going to launch in a few weeks. And I just sent this thread to my engineering team demanding that they swiftly integrate One into our web draw, or they will walk the board! Just kidding. We're not really pirates. Anyway, amazing work, looking forward to using it for many projects here!!!
Deleted Comment
I'd consider Next.js a giant step backwards, frankly.
Can't help but roll my eyes here