leebenson / reactql

Universal React+GraphQL starter kit: React 16, Apollo 2, MobX, Emotion, Webpack 4, GraphQL Code Generator, React Router 4, PostCSS, SSR
https://reactql.org
MIT License
1.82k stars 174 forks source link

Comparison with Next.js #2

Closed sedubois closed 7 years ago

sedubois commented 7 years ago

I think GraphQL + React + Apollo + Webpack + SSR is a good combo :-)

How about using Next.js? 2.0 just came out: https://zeit.co/blog/next2 Then this repo could focus on integration of Apollo, styling, asset handling, etc.

I made an proof of concept trying to assemble that stack too: https://github.com/relatenow/relate Hoping to bring these ideas in my production system as soon as I can.

leebenson commented 7 years ago

Thanks @sedubois.

Putting together a comparison vs. Next.js and other starter kits is on my to-do list.

I'm currently working on a gitbook layout for the manual and planning to put together some tutorial videos, then I'll clarify how this differs from what's already out there.

As a brief meantime summary -

Next.js is awesome, and more comprehensive than ReactQL. It has its own router, and more focus on features such as declarative pre-fetching. It's much closer to a framework than a starter kit and introduces some new syntax and concepts. You're buying into a new ecosystem, albeit one with (relatively) lightweight tooling.

ReactQL, by contrast, is strictly a starter kit. It uses third-party mods exclusively, with the 'glue' necessary to make everything play nicely. Its raison d'Γͺtre is to solve the tedious set-up code that every project needs, but usually takes way too long to figure out how everything slots together.

Both kits are quite opinionated; ReactQL uses postcss instead of styled-jsx, React Router v4 instead of a custom router, Koa instead of Express, etc. It also has an opinionated styleguide based on Airbnb that reflects my preferred syntax/formatting. I made stack choices after experiencing many of the alternatives, and IMO these represent the ideal stack. With Next.js, you bring your own data loader. ReactQL is specifically intended for Apollo and GraphQL.

You can achieve much of the same things with both kits. Next.js tends to have a 'Next.js way' of doing things -- e.g. prefetching a page is just a prefetch attribute in the built-in <Link> component , whereas in ReactQL you'd use standard Webpack tooling to handle code-splitting and create a custom React component that updates the UI once it's loaded. I may introduce custom libs to handle common use cases like this in future versions, but the general response to most of these requirements is "use the standard tooling."

In short - the point of this starter kit is to make opinionated choices on data fetching, code bundling, styles, UI etc based on popular repos, and curb user fatigue of trying to get all of the common 'stuff' working together well. It's focused more on slotting the parts together well and providing common patterns for handling stores, data loading and SSR, than introducing anything new.

It offers a starting point that's intended to be hacked and extended, rather than abstracted away with new code.

I'll better illustrate this with a blow-by-blow comparison of features and how-to guides once the gitbook is up :smile:

linonetwo commented 7 years ago

Besides, I believe this repo will be a good teaching room for young front-ends since my first front-end experience were learned from https://github.com/erikras/react-redux-universal-hot-example, which taught me a lot.

leebenson commented 7 years ago

@linonetwo, thanks for sharing your experience with a previous starter kit. That's definitely one of my aims, too - to provide enough of the 'glue' and documentation surrounding the set-up code, so that devs feel they have an intuitive sense of what's happening under the hood.

Even if you wind up ripping the kit apart and just using it as a stepping stone to something else entirely, hopefully you'll walk away with a worthwhile guide. I'm planning to record a bunch of example videos and tutorials at later stages that will tackle use-cases beyond what ReactQL provides out the box - will post those to my YT ReactQL playlist and docs as they happen.

sedubois commented 7 years ago

Thanks @leebenson for the explanations πŸ™‚

My point wasn't to say that this or that repo is better in terms of their technology stack. I agree there are nice choices here. The main point is that this is a boilerplate, i.e. it might give a nice starting experience, but then it doesn't help the user with upgrading and maintaining their project. reactql new creates plenty of config files, and then the user is left on their own. They are condemned to live with all the bugs/limitations that are present in reactql at that point. I previously made the mistake with react-boilerplate and react-starter-kit, they offer nice initial value, but no maintainability.

That's why I think a synergy could be found between reactql and a project such as Next.js. It's IMHO very valuable to provide as much code as possible in the form of dependencies which can later easily be upgraded.

So IMHO it's inaccurate to say that such a starter kit will "curb user fatigue". Also it's inaccurate to compare e.g "Koa instead of Express". Next.js doesn't force the use of Express, you can use any custom node server. As well, Next.js doesn't necessarily use styled-jsx. And if Next.js has some limitations, it's easy to contribute to make it better.

I'm saying all this because I think much good can be achieved through collaboration πŸ™‚

leebenson commented 7 years ago

@sedubois, I'd be interested to hear specific ideas on what a collaboration might look like.

I have no doubt that Next.js et al represent more 'complete' choices of a framework. My intention with this starter kit isn't to become another framework -- it's to take care of the somewhat ambiguous set-up of disparate (and popular) components around the React and GraphQL ecosystem.

Rather than encouraging abstraction through another framework, with ReactQL I aim to expose the 'standard' hooks between the various stack pieces directly, and provide enough commentary in the starter code to educate on where the pieces join.

If there's a way to build a 'Next.js version' of this kit, I'd be interesting in supporting the community. But, I'm currently unclear exactly how that might work, since ReactQL is simply a kit of existing components with a thin CLI to wrap it. Which of the stack would remain in a Next.js context? What is Next.js lacking that ReactQL might be able to provide?

Open to your thoughts.

sedubois commented 7 years ago

@leebenson you can keep the non-framework philosophy for many things, just simplifying it for those things that most users won't want to configure and maintain themselves. (Those things that will actually prevent users from being interested in this project.)

So I'd suggest adding next.js as a dependency beside the other dependencies you already have, and progressively let it handle what it can: webpack, ES6, SPA, SSR, page-splitting, HMR, chunking, routing, dev/prod optimizations, etc. If you manage to let Next.js take care of these things, that's a lot of maintenance burden that you'll take away from Reactql's users' shoulders.

What you don't agree with, you could either help fix within the Next.js codebase, or you could configure it yourself on top. Next.js has configurability through custom server, custom webpack, and custom babel. (and hopefully in the future it will evolve either towards universal webpack or universal babel: https://github.com/zeit/next.js/issues/1245)

So the value you could offer on top is the integration with Apollo, Graphcool, Redux, and your own choices of liting and styling, and probably other things I'm not aware of.

Once Reactql would be streamlined in such a way, you'd then have more resources to provide, if you wish, other essential things that many users need, such as authentication, PWA, offline-first, and all the other amazing things where a boilerplate/kit would truly shine.

The more experimental features would be provided as plain code, and what stabilizes and doesn't really make sense to let the user maintain, would be available through a dependency (either your own or an evolution of what's out there). E.g for offline-first there's the new redux-offline.

(NB: I'm not from Next.js, I just followed that project for a few months and I think it's quite promising, and intend to migrate my production system to it: it would therefore have been great if Reactql was itself based on it so that I could use it to scaffold.)

Just some thoughts πŸ™‚

leebenson commented 7 years ago

I appreciate your thoughts, @sedubois. I agree that having a de facto framework handling the lower-level plumbing would shift some of the maintenance burden upstream. There are a couple of disadvantages though that I think are worth bearing in mind, though, IMO:

1. Frameworks have a tendency to fall in and out of favour.

Earlier in my professional career, I often got caught in the 'marketing' and eagerly aligned loyalties with the framework du jour. But, after 20 years of watching every 'next big thing' fall out of favour and devs ultimately jump ship to the cool new stack, I'm leerier of building a project based on single provider that may or may not exist 6 months from now.

I think it's far healthier for a developer to adopt the attitude of knowing the stack intimately, and having enough experience with it to swap out pieces as necessary, rather than entrusting important building blocks to a framework that may fork from your expectations sometime in the future. I can't tell you the number of times I've wound up shifting entire projects away from a stack I've pinned expectations to, only to find as soon as I needed to do something different, I didn't have enough control over the 'internals'. At those times, the descriptor 'starter kit' highlights exactly what a repo like this is good for... giving you a push with training wheels, but ultimately setting you free to ride on your own.

You're trading control for the convenience of automatic updates and maintained packages, granted, but you're also getting a peek behind 'import' statements to see how it's all wired together. I've not yet encountered a significant project that didn't need the control, at some point.

For that reason, I think it's far more practical to a adopt microservice-based approach and know enough about the nuts and bolts to know what needs changing than trust code bundling and other lower-level details to a 'done for you' framework that you're not directly encouraged to take charge of.

2. Expect things to change.

Very little of the code in ReactQL today existed even a few months ago. Apollo is bleeding edge v1, React is making strides with Fiber (not yet featured), React Router 4 is still in beta, Koa has barely hit v2, Webpack has been sporting the 2.0 badge for just a few months after redirecting its 1.0 traffic. The point is, very little of this stack existed even 18 months back, and I expect most - if not, all of it - will be dead or vastly refactored in the next 18.

When the only constant is change, I'm not sure how practical is it to abstract the details away from a developer who is building projects on top of this stuff and who's performance of the parent project depends on it. I fully expect pieces of ReactQL to get swapped out, replaced or killed completely; rather than hide those details, the point of any good starter kit is, IMO, to expose them and make it clear where the glue is applied so it can easily be replaced with something else when that piece no longer makes sense.

More than code, I actually think overarching benefit to GraphQL will be its commentary and the video guides I'm planning on producing, to tackle common use cases.

None of this is a slight against Next.js or any other framework. I think Next in particular is doing a fabulous job at providing modern framework features, with a low barrier to entry. But I'm still sure exactly where our philosophies converge, and what value-add I can provide that the plug-in community hasn't already tackled.

My plan was never to support an existing framework - it was to share what I had learned with (what is currently) my favourite way to tackle UI and GraphQL on the front-end.

I'll keep an open mind, though, and if it becomes more obvious that I can be providing more benefit with another approach, I'm open to it.

sedubois commented 7 years ago

Agreed with all that πŸ™‚ And actually these are IMHO arguments to depend on Next.js (until the possible day when it dies). Because using Next.js reduces the number of direct dependencies in the user's project.

From the end-user's point of view, what matters is to reduce their amount of direct dependencies while delivering the value they need. Because then the maintenance burden (and the switching-between-libs when they "fall in and out of favour") is then provided by the maintainers of these direct deps (i.e. you, in ReactQL's case).

sedubois commented 7 years ago

We always need to build upon prior/lower-level work if we want to provide something better, that's the essence of technology. Otherwise we'd all still be writing in assembly...

leebenson commented 7 years ago

Because then the maintenance burden (and the switching-between-libs when they "fall in and out of favour") is then provided by the maintainers of these direct deps (i.e. you, in ReactQL's case).

To refer to the 'training wheels' analogy again, I think the distinction is that ReactQL helps you at the start of a project. Next.js et al require you take them along for the ride.

There are pros and cons to both approaches. If Next survives the next 5 years and takes care of the 'plumbing' whilst providing neat abstractions/patterns/libs for routing, SSR and whatever else you might need, and you only ever need to write your own code, that sounds like a situation that would suit many developers perfectly.

In my experience, any significant project ultimately outgrows its framework. At those times, a starter kit like ReactQL might be just enough to inspire good/recommended patterns, but without the heavier buy-in of a framework. The downside is that the starter kit you spawn now probably won't be the same starter kit you spawn in a year's time, because some of the pieces may have changed from under you.

Two different approaches. Maybe there's some common ground, or a 'ReactQL.next' -- I'm just not sure right now exactly what that would be.

sedubois commented 7 years ago

I think there's a valid point here that it would be very helpful if Next.js had an "eject" functionality similar to create-react-app. It would solve the fear of being trapped if/when it's no more relevant.