Hacker News new | past | comments | ask | show | jobs | submit login
Solito – React Native and Next.js unified (solito.dev)
216 points by reimertz on March 14, 2022 | hide | past | favorite | 50 comments

Creator of Solito here. I've built a number of React Native libraries (Moti, Dripsy, etc). Happy to answer any questions. I originally gave a talk at Next.js Conf about how/why we use Next.js with React Native: https://www.youtube.com/watch?v=0lnbdRweJtA

Navigation is the hardest piece of sharing code across platforms. Web has plain URLs for navigation state, whereas apps have complex sets of nested navigation patterns (stacks, tabs, modals, drawers). By combining the approaches into a single mental model and API, devs can build for Web and Mobile with ease. This is touched on at length in the "Methodology" and "Gradual Adoption" sections of the Solito docs.

The gap between web devs and native devs is shrinking. This stack enables you to ship native apps and websites with a single codebase. I'm the only frontend engineer at our startup, and I was able to do just that as we scaled to thousands of users (see https://beatgig.com). My goal with Solito is to 1) provide the code to let others do it, and 2) perhaps more importantly, document clear patterns to deal with platform differences.

How did you come up with the name? Doesn't solito mean something like "a little lonesome" in Spanish? This is two products combined, wouldn't something like "festoso" make more sense?

Solito gives a “solo dev” the power to build for multiple platforms.

I built our entire product from scratch for iOS, Android and Web. Rather than rushing to hire a team to do each thing, I felt that if I built the right abstraction layers, it could all be done by one person.

It can be a lonely road when you’re the only one, but Solito helps you feel a little less solo

Just to give you another perspective :) I love the name, I think it conveys what you just said. I really like direction you took and utilizing Next.js and React Native is wonderful combination.

Especially in Latin America, the diminutive is used much more widely than just to communicate "small" (noun), or "a little" (adjective). Perhaps "solito" here can be interpreted something like "quite a cowboy".

looking forward to Arturito ;D

Just wanted to send you a sincere thanks for all your work around RN and NextJS - your libraries and patterns have really helped our team cover a lot of ground :pray:

Glad it's helpful!

This looks cool, nice work! As an alternative, if you’d like to have a single web-based codebase for iOS/android/pwa/etc using Next.js then you might like this approach using Capacitor: https://github.com/mlynch/nextjs-tailwind-ionic-capacitor-st...

The benefit over using RN for this is being able to use libraries like Tailwind on all platforms and having a true single codebase.

I don't view a single codebase as the goal necessarily. While I see the benefit to doing a WebView everywhere, I prefer the React Native approach: write once, run anywhere by using the underlying native components of each system. Because it has such a great unified API for building UI, React Native is a good abstraction to use the same code everywhere. But what draws me to it is the fact that it maps onto native elements.

That said, I'm sure there are good arguments for Capacitor!

I'm a fan of Capacitor and Ionic for the reasons you mentioned. That said, they sit in a web view, whereas this library seems to support true native navigation which is really exciting.

Also check out tailwind-rn for using Tailwind classes in React Native. The latest version even supports Tailwind 3 JIT compilation so you're bundling minimal TW class adapters.

and only at the expense of search discoverability, rich previews, and potentially a lot of performance on all platforms :)

at the expense of search discoverability?

yeah dude. loads all the pages dynamically with SSR off: https://github.com/mlynch/nextjs-tailwind-ionic-capacitor-st...

wow, that's a weird limitation.

The README says: "SSR is currently disabled for the Next.js app as the app will be fully client-side rendered for iOS and Android. This is a limitation we are working to address in a future update."

I guess it's because CapacitorJS pre-bundles the entire PWA for the App Stores:

"Of course, you also could load the app completely remotely by changing the server.url configuration for Capacitor to point to your SSR'ed Next.js app, but that has other challenges such as App Store approval if the app doesn't check the boxes for Apple to qualify it as an app that has enough native integration (at that point this is on you, not Capacitor)"


But I don't understand why SSR would be disabled for the NextJS PWA on the web?

Maybe the creator Max Lynch aka. @mlynch aka. @yesimahuman could provide some insight here.

For anyone interested, here is the keynote introducing Solito from Next.js Conf 2021 by it's creator Fernando Rojo.


I suspect I'll end up using this ASAP just for the useParam hook, as it's a pattern I like quite a lot (page state as query params) and is a big ol' pain to maintain and deal with edge cases.

Applause to Fernando for this. His work on react native open source has been incredible. Definitely check out his other projects Dripsy and Moti as well!

Wouldn't Remix be a better fit? It's easier to run in more client-orientated environments.

Currently, I like to have the API and web pages (signup, marketing, policies, etc.) made with Remix.

Then, the cross-platform app (native & web) can be made with React Native / React Native Web using React Navigation as the router.

I can certainly see being able to combine those two into one as a plus, but React Router / Next Router and React Navigation conflict. React Navigation is needed for a nice app experience.

Someone has brought up adding a Remix integration to Solito, too. It's certainly possible from my end, the question is if Remix would make it possible. Many remix APIs like Form seem to be very browser-specific, so it wouldn't share nicely with React Native.

That said, I opened this discussion on the Remix repo a while ago: https://github.com/remix-run/remix/discussions/1578

If you're using shared screens outside of Remix marketing pages, though, then I imagine a solito/remix could exist to bring the same features the Next integration has to a Remix one.

Understandable with web specific apis like form. My main wish is a React Navigation and Remix adaptation to bridge native to full web.

Doesn't remix very much want to handle the routing? Homestead you mashing that with react-navigation?

As does Next.js, does it not? Solito uses next/router. I updated my comment to reflect this dilemma.

This is why I currently separate web pages & API from the cross-platform native/web app.

Adapting Remix to React Navigation would be the solution if possible.

Sure and that's what this library bridges. I see the appeal in remix for building interactive apps the "remix way" with forms, relying on web/http conventions etc. I also like that it brings nested routing back to metaframeworks. None of that will translate well to native. As an api+website framework it doesn't look more appealing then next.js to me, which is a little more unopinionated and thus easier to adapt to cross-platform.

I guess my point was this library bridges next router similar to how it could bridge react router with Remix. Neither are a great native experience that React Navigation provides.

"React Native and Next.js" sounded to me like you were trying to do server-side rendering for react native apps, it's the first thing I associated with 'next.js'

But this is more about navigation if I see this correct? So more in the direction of react-router

React Native + Next.js refers to using the same code in both a native app and website (built with Next.js).

The hardest part of sharing code between apps and websites, however, is the navigation code. Websites have flat navigation. You have one page mounted at a time. When you navigate to another page, the original one unmounts and a new one renders.

Native navigation has a different paradigm altogether. Rather than use simple URLs to account for most of the navigation state, native apps have complex tabs, stacks, and more. When you change tabs on Spotify, you expect the previous tab to maintain its state, scroll position, nested screen, etc.

Given all of these considerations, it's previously considered impossible to use the same code for apps and websites, even if they're all written with React.

Solito solves the navigation problem by offering a unified API across Web and Native. This lets you write your code one time with React Native, and use it on both iOS, Android and Web.

From the docs:

> Solito treats URLs as your source of truth. Your Next.js app and React Native app don't communicate at all. They live in total isolation. Solito works by doing this: give me a URL, I'll detect what platform you're using, and then I'll figure out how to navigate to the screen for that URL.

I also was expecting to see some sort of SSR, got clickbaited

RN views can already be SSRed for a while now.

The problem has never been SSR but the divergent navigation patterns/state between web and mobile, for which it's not easy to build a shared abstraction.

Looks like you feel clickbaited because you are looking at this on the surface

It's great that this is as much a library as it is documentation on good patterns for this.

I don't use react-navigation, so I won't be able to use the library. I actually arrived at a very similar setup of a Link component that is a different implementation per platform. I think it will become even more similar after learning from this code and documentation.

I didn't know React Native + Next.js was a thing? What is the goal of doing that? I don't know what problem Solito is solving, some helpful context would be nice for those of us who are foreign to the problem.

It's mainly cross platform components (Fernando refers to them as screens) that can be used on the web, iOS, and Android. In Next.js, you can import these components as pages. On iOS, file based routing does not exist. Solito fills in the cracks. His video at Next.js Conf was really informative: https://www.youtube.com/watch?v=0lnbdRweJtA.

React Native + Next.js definitely has appeal to me. However, I'm not sure how future proof this API is. Unless I'm missing something, it looks like it locks you into data fetching at component render time. Facebook have been working hard in recent years to move away from that (<Suspense />) and routing libraries like React Location (https://react-location.tanstack.com/) offering asynchronous routing APIs seem like more promising approaches long-term.

Those kinds of implementation details won't be hard to add to Solito. The API I'm using is that of Next.js. If they adapt to suspenseful approaches to routing, Solito will too.

There are also experiments in the works to make React Navigation lazy load code with suspense on the Native side by bringing Webpack to Native: https://github.com/EvanBacon/expo-auto-navigation-webpack

Another added bonus of this approach is that it will have a pages/ folder API like Next.js.

I don't see why Solito won't be able to support these use-cases as they arise.

That's fair, you're limited by the technologies you're using. I guess that's a problem with these sorts of libraries, you can find yourself being "the lowest common denominator". Of course, your library is very useful, and there are plenty of apps that I imagine can just drop in Solito. So this isn't at all to detract from its real-world value today.

However, as much as it's convenient to get up and running (with bundle splitting), the file-system based router is in my opinion probably the weakest part of Next.js. It would be top priority on my list of things to go. The main issue is it's fundamentally not type safe.

For example, Solito's useParams() is fragile because refactoring can easily cause param substitution to come out of sync with param consumption (in another component). My most recent solution (not in Next.js) for this is:

  const {partnerId} = useRouteParams(routes.tails.partner);
That's 100% type-checked. Creating a URL for that route is also type checked and done like:

  routes.tails.partner({partnerId: "blah"});
I'd really like to see routing libraries adopt type safe practices.

EDIT: I suppose the file-system based routing could be kept if you pair it with code generation. Maybe that's an option?

Been away from React from two years and this stuff is all-new to me.

Maybe I'll wait another few years for it to settle down before looking again...


lmao!!!!! foreal man

"Solito is the missing piece for using React Native with Next.js to build powerful cross-platform apps."

What was missing though?

A solid strategy for bridging pages/urls of next.js with the screen/navigation patterns on mobile.

To help illustrate what this means, my team recently rebuilt an entire next.JS app in React native using almost identical code apart from a few browser-specific components. Since the next app was tied to the router state, we had to rewrite quite a bit of that logic in React native land, but for no added benefit to our app. It was just extra work and now extra maintenance. We tried to share as much code as we could, but that becomes an effort of its own eventually.

It seems like Solito could have prevented a significant amount of work, reduced code duplication, and let us release our mobile app a lot sooner.

If Solito does what it says well and porting to it wouldn’t be difficult, I wouldn’t be surprised if we made the move. This is a very compelling pitch to a team with a next.JS app and a React native app sharing the same business logic.

This will help open a lot of doors for us. Very interesting project.

I don't get this. Isn't the main benefit of next.js proper splitting of server/client code, prerendering and such?

None of that is needed on a native platform.

It's about using a single codebase ("write once, run anywhere"), that can use React Native on native and NextJS on the web. Solito is the abstraction that allows using the same navigation abstraction for native and web.

mad props to Fernando Rojo for not only creating these libraries, but also for solidly documenting them (including his journey and rationale)!

This looks super cool.

Rookie question from a Web dev here - what functionality does react native provide that isn't available on Web?

React using React Native is almost identical, with a few key differences:

1) No HTML elements. React Native provides some low level elements for views, text, etc. The rest depends on the platforms and packages you have installed. 2) You can't use CSS, so you use something that is similar to CSS (including flex box), but isn't cascading. 3) Since ultimately React Native results in native views being rendered, you can also use some of the native view debugging that exists. 4) Changes made in React are batched up and sent to the native side of things, which results in some performance characteristics you don't see on the web or native mobile. There is also a difference between iOS and Android performance. You feel this a lot more on mobile than on the web.

1. you can code share with iOS and Android. 2. the primitives provided by React Native solve the many bugs you get from low-level CSS and HTML.

there are many other reasons, I touch on all of them in my Next.js + React Native talk at Next.js Conf: https://www.youtube.com/watch?v=0lnbdRweJtA

I built https://beatgig.com with React Native and Next.js as the only front-end engineer and designer, and our iOS app and website share 99% of code across hundreds of screens.

The benefit is that you can make an app with platform-native views and navigation. If you don't care about this native "feel" than it doesn't matter and capacitor may be a better choice if you just need access to some hardware or push notifications.

I have personally drunken the kool-aid to the extend that I'd rather develop a pure web project with react-native-web because I like the choices/constraints it introduces but I don't think that's the case for most people.

I would guess that the point is to share more code between web and mobile.

is there an analog for NativeScript?

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact