I've built an relatively high-traffic SSR'd React website from scratch, and I've done the prototype for the rebuild of the website at work (we're moving away from Gatsby). The reason I'm considering Next is precisely because what i'm building isn't a "web app" like Spectrum, but merely a website (with some e-commerce features).
The sweet spot for Next.js seems to be that you're trying to make something that resembles a traditional pre-React-era website in structure, but just happens to be built using React. Once you're building an app, it doesn't feel like the best tool for the job. You can obviously bend Next to your needs, but fighting the framework is the last thing you want to be doing in the first year of a startup's life.
They managed to get an exit, which is a great result. And obviously they've learned a lot in the process which is another great outcome. But I can't help but feel that having just one experienced engineer on the team would have made their road a lot less bumpy.
For A/B tests you could generate all the variations during build and have whatever sits in front of the site be responsible for serving the right files, but this just feels like an admission that, yes, static sites have their limits. For user-specific stuff the only real solutions are to go back to having pages be server-generated, or go all in on technologies like Edge Side Includes.
Hence why React is not the same as React-Native-Web.
If they would have used react-native-web, he would have saved some time writing the Android (or IOS) apps. Because he could have reused the code (he said that too).
This is what I have done, anyway.
Also react-native-web is very very high quality library.
I am just amazed at the quality Nicolas Gallagher is putting out.
My app now runs on web and via browser on android/ios with all the magic of responsive UIs, reshaping all those positions when a user rotates the screen or zooms out.
I am wondering, on occasion why I spent time on native apps (even with React Native) -- at all, as React Native Web (with a bit of React-bootstrap) -- are just amazing.
Wrt next.js, at least when I looked at it mid last year, did not support routing with React-router. And for me it was a big deal, I did not want spend time on learning specifics next-js routing.
Instead I went with
which supports React Router for routing, which I use Android/react-native and React-native-web, uniformly.
React-router, is also very good and useful library with nice, intuitive architecture for routing.
At the end, I decided for my need the Server Side rendering is a later-stage item. So I have not spend more time on it.
I suspect Spectrum did not loose much traffic because their app is not using SSA routes.
Zulip chat app (may be they are spectrum's competitor, not sure) - uses React Native for mobile (https://github.com/zulip/zulip-mobile ), but something else for web. As a reference.
Is the answer any different for React Native? (I guess you lack a server-side renderer at that point, so maybe it's easier to plan to do everythig in React if you plan on using React Native?)
I'm doing it at work in an app that's still 80% Backbone. We're replacing Backbone Views piecemeal, with each chunk becoming a separate React component tree . It's certainly easier if it's all one big React app from page load, though.
I haven't used React Native myself, but I _think_ you can use RN in a similar way. I think I remember reading that the Facebook app uses RN for certain pages, but not others.
I'm curious about what you consider complex about an SSR setup with React, I'm becoming very familiar with the internals of React and frameworks like Next and they're often relatively thin wrappers over the built-in features.
Assuming that you make somewhat reasonable choices in the first place, technology likely won't become a problem for quite a while. At which point you either have succeeded enough to have the resources to fix the issues that come up, or else you have bigger problems than technology and should focus on those instead.
RethinkDB sounds terrifying though, I’d hate for my DB errors in production to literally have no idea what to do, it makes me feel sick thinking about :-)
I think we should aim for kludgy but boring working solutions first - for example I’m tempted to write a redux middleware that sends dispatched actions to the server and manually sync, order and manage conflicts in these events to build a “perfect” system where front end state management and backend CQRS perfectly marry up. It’s a terrible idea because I know how to build the Podcast app I’m making perfectly well without any of this nonsense.
I think several databases actually do this.
For example, Alerting in MarkLogic
Another example is
Percolations in Elastic Search
My personal view is that those are useful features, however, often they indicate poor architecture where developers did not create proper APIs that put data into the database, and instead rely on database 'triggers' (or percolations/alerts) to notify the 'world' about changes.
Those kinds of notifications, should really be coming from either data consumer or data producer APIs, -- not from the database engines.
Of course, that is a testament to the quality of the documentation and the source code of PostgreSQL.
The fact that the Logical Decoding and Logical Output features were built for replication means that some decisions were taken not-in-favour of publishing changes, obviously, but it works pleasantly and straightforwardly. Even writing a custom logical output plugin would be simple, because Pg does all the transaction tracking, position tracking, change decoding etc.
Should be okay for 99% of needs no?
The idea of simply being able to listen to a query without any additional work sounds like it could be really attractive in certain situations.
Sounds a lot like RethinkDB changefeeds https://rethinkdb.com/docs/changefeeds/ maybe check that out first :^)
Nice idea in theory. Can be awful in practice.
For example in enterprises it's very common to see applications last years or even decades. And so that kludgy but boring solution would be the foundation on which you will have hundreds of engineers and years of work built on top of. And because your kludgy but boring solution worked in the beginning you rarely go back and redo it.
Hence why you see a lot of upfront developers built these over-architected monstrosities. It's because they are trying to cater for a decade of possible new features.
Dev Person: "Hey boss I finished that X, but I used a framework that hasn't been cool for at least 5 years but it will probably last a decade without a rewrite and everyone can build on top of it."
CEO Person: "That sounds great, please keep doing more of that!"
Admittedly, I like playing with the new shinies as much as the next dev, the above scenario sounds horrible to me to :)
You don’t waste time implementing features you “know” you will need in the future (you don’t know). You don’t waste time handling scenarios that make your feature theoretically complete and elegant but that have no significance to the users of the product. You go quicker to market and can more quickly iterate on your product.
I think a much better approach is to implement these kludgy solutions that apply to the specific problem being solved. Then, you can revisit the code when it makes sense (e.g. the scope of the feature is being expanded, or just do it regularly to keep things healthy). Generally holding off on implementing things you don’t need will put you in a better position to implement the things you will need when you reach that point in the future.
If you start pushing the data from your application itself then you introduce the problem of dual-writes (what if S3 write failed? what if RDBMS failed?).
If instead you treat your RDBMS as the source of truth and use something like PostgresSQL's logical decoding feature to listen to the replication stream and then push the events from that stream to S3 you can achieve guaranteed-eventual-consistency.
The best way would've obviously been to make your application write to a Message Bus (Kafka etc.) and then some other application would persist that message to your RDBMS. This approach requires more development effort and introduces all the issues that distributed systems face: Read your writes, read follow writes, write follow reads etc.
I am currently researching how to do this properly. What would you think would be the "boring but reliable" way to do it?
Previously I had believed if you had a tool that solved the exact problems you have, then you should use it. I hope I'll resist such an urge in the future by having a little pragmatic angel on my shoulder reminding me of the danger of underused software. No software is perfect and even tough you might be able to fix software when it is open source, you paint yourself into a corner when you will necessarily have to fix it.
I felt my experience was matching some of the authors woes and I urge anyone that chooses technologies to think one step ahead and learn from our mistakes!
2. Test deployment
3. If success, great go home at 8:10pm.
4. If fail, rollback, retest, go home at 8:20pm. Come in next day and fix in source code and schedule new deployment.
5. To avoid #4 in 99% of scenarios, use a staging environment.
We do however have a staging environment already that is frequently updated and updates available within an hour from starting the update.
Thanks for the concern and tips nonetheless!
> Optimize for iteration speed and flexibility.
Faster, but not necessarily better. Reusing web technologies for mobile is almost always an optimization for developer time, which might work early but I feel almost always ends up needing to be rethought in the future.
React-Native uses native widgets and doesn't bring too much Web tech.
You can still replace screens with native modules later if they don't perform well.
If you start, you need to get something usable out of the door quickly before you run out of money.
Experienced developers spend most of their time thinking because experienced developers tend to work in fields where at least the problems are known, as well as some best practices for solutions. That's how they got to be experienced, after all. But this is also why experienced developers, when they choose to found startups, often end up with B2B startups that slot into an existing industry structure, not startups that end up defining the industry.
(Source: experienced developer now founding a startup and wrestling with just how little all that experience matters when it's not even clear what problems will dominate the industry or if the industry will even come to exist.)
(Having used react-native-web for a project once, I also question whether it actually would've improved things: the HTML generated by react-native-web is terrible for SEO, and they might never have gotten to the point where they had users asking for a mobile app if they'd gone this route. Hindsight is 20/20 and often forgets about obstacles on the path.)
Both inexperienced and experienced developers can work effectively in problem domains where there is no clear path to a solution, and where even the problem itself is underspecified and changing. It takes some practice to figure out how to work effectively in such an environment, but at some point you run out of opportunities to have gained deep practice because the problem is too new.
Mistakes: I did plenty of backend work (e.g. gRPC services) just to realize it didn't mesh well with the frontend when I started to build it. I over-complicated the feature set and realized I built a foundation for an MVP that would take forever. I abstracted everything because in my head I thought about all the future uses. I worked on an advanced-tech frontend that kept me bogged down in frontend development instead of doing the whole thing. All of these are typical mistakes of pie-in-the-sky side projects sans deadlines.
For the latest iteration I have changed my approach. I am building the dumbest web UI w/ the dumbest in-memory-only-at-first backend with minimal abstractions. The initial web UI doesn't even use any JS which I know can seem like extra work w/ HTML forms and the like, but the raw simplicity is easier to build now and take away later than something more complex. I'm deferring lots of features. Once I reach a web-UI-only MVP, my next step will be to abstract what already isn't on the UI front and make a Qt app that uses the same abstraction. I've found this to be the easiest way to get some UI idea reuse across different paradigms. I can add more UIs including an API, terminal, mobile, etc with this approach. For the backend, simple gRPC backed by a "db" of in-memory data structures for now until I abstract that to allow sqlite to join and then on from there. It is very refreshing to develop a full-stack app without a complex full stack. The major benefit of developing a stupid-web-with-in-memory-db MVP? Testing and quick iteration. I've found you can iterate on core structures/ideas or you can iterate on external tech/features, but you can't do both at the same time.
That depends on your product and your audience! Many (probably most) B2B apps work poorly in the constraints of mobile. If your users spend their 9-5 hours buried in your app at the office, they probably value things like hotkeys, multicolumn layouts, and high-information-density pages.
Will the new tech give you leverage over companies who don't use it or will it be discontinued and leave you with unmaintained crap?
Will the old tech give you a stable base to build upon or will people with new tech overtake you with less effort?
Change feeds sounded cool, but we never used them in the end, because of the latency.
I didn't use react-native-web, because back in the days it was alpha and later there was react-native-dom, which seemed like a better approach, but I have the feeling it doesn't have much pace to get anywhere any time soon :(
I went through the codebase, and the content itself is static. I'm not attempting to bash the decision to use next at all. I'm only looking to grow my understanding of the usage of next since I see it being mentioned a lot.
The question I have is, why use next/react for what appears to be a static site. Or, why not use static html + markdown?
Again, not bashing. Just looking for reasons that I might have missed due to my lack of understanding/context.
(Not sure if this holds for Next.js as well, since I believe it does a few other things too, but React Static has been a breeze for me.)
Randoms who comment on Reddit. It’s not a high bar.
I actually prefer using markdown than fighting with an opinionated WYSIWYG editor. (Looking at you Word).
Barrier to entry being low is really misleading. It never was low and because of how generic and complex computer systems are, it isn't low now. It will only get more complex as time goes on, unless everybody pulls together and fights tooth and nail to go back to writing small, fast software. Anybody considering "I just want to program and not worry about low level details! Which framework can I use?" should stop dead in their tracks and seriously consider what they are doing with their life.
It's not that hard to wrap it as a React component and get going with it
Something that I have always disliked about HN is the lack of the ability to delete comments and accounts. OTOH, Slack etc are private and lock up good content/discourse away from search engines. Hopefully, spectrum will offer a better balance.
For a while, Erlang was quite popular in that area, but as some orgs only used it for that and thus didn't get too deep in the tech stack, they were eager to switch to something they imagine they know a bit better.
I would love to learn Elixir though, from what I have heard it is great for real-time!
If I wanted a lighter solution, I'd probably give https://trix-editor.org/ (made by basecamp) a try.
Small backups took hours. It was extremely difficult to tune.
We once had a 5 machine cluster. We decided we needed to re-balance the cluster. The thing COMPLETELY CRASHED and went up in flames, caused us to have to stay up all night fixing it.
It was the same day we decided to rewrite our application to not use rethinkdb. Best decision we could have made.