Not Another Framework
remix.run
remix.run
These frameworks aren't so much frameworks, as they are framework builders. For small projects, they get out of your way. For larger projects, their lack of defaults and structure slowly becomes their own undoing. Eventually you get a bad reimplementation of one framework or another with absolutely abysmal security.
Case in point: every Sinatra site I've ended up dealing with has turned into a bad version of Rails. ( Hand-rolled authentication, unsafe session handling, no CSRF protection, buggy form validation...)
A field of infinite possibilities seems like a great idea, but you quickly realize it's actually a sea of infinite decisions.
Once abstraction became possible, the debate between framework or no framework started. And hasn't stopped. Nor do I think it ever will. :)
Talk about misleading:
> When we design Remix APIs, this is something we think about. We want your experience with Remix to transfer to web development generally.
It doesn't. Or, rather, it does nothing different than React.
> instead the equivalent JavaScript Webpack monster interlaced with the endless NPM dependencies we know and love.
Yup. Because Remix translates those components by pure magic, with no dependencies
> npx create-remix@latest
> cd node_modules
> ls -l | wc
379
Oh look. 379 dependencies before we even wrote a single line of code> Wherever the browser has native support for some functionality, Remix uses it so that you don't reinvent the browser as a thin JavaScript layer over every one of your projects.
Remix's own docs show this is not true. It adds additional abstractions everywhere, and "uses underlying browser functionality" literally to the same extent as everybody else.
Example, fetching data:
Remix polyfills the fetch API on your server
so it's very easy to fetch data from existing
JSON APIs.
Instead of managing state, errors, race conditions,
and more yourself, you can do the fetch from your
loader (on the server) and let Remix handle the rest.
Remix optimizes the user experiences by only
loading the data for the parts of the page
that are changing on navigation.
So it creates a polyfill, and adds layers of abstraction to make it work. You can say, "it's because it's not in the browser, but on the server". Yes, exactly, Remix doesn't even have documentation on how to use all that goodness on the client. Instead, it creates a huge, complex, and undoubtedly brittle tower of abstractions to make all that work on the server.But worse, as far as I've ever been able to tell. I haven't done enough web front-end development to really have a strong opinion on front-end frameworks, but I have done a non-trivial amount of it. I did work with Javascript back when it was new and then followed the jQuery "revolution". While I observed that jQuery actually did eliminate a fair amount of code, I also observed that is also eliminated all of the troubleshooting techniques I'd worked out for Javascript development. I couldn't place breakpoints in firebug any more because all events were being handled by one massive "event handler" (and then re-dispatched to jQuery's own custom reimplementation of the event handler infrastructure that the browser already had built into it). I found Angular to be effectively the same. By then it was worse because Chrome's debugging tools were top notch for "vanilla" Javascript development - much better then firebug had ever dreamed of being, but mostly useless in Angular unless you were lucky enough that a problem included a stack trace into some code that you wrote. I've never used React, but skimming through the high-level docs, it looks like it's more of the "let's write a web browser in Javascript and run it in a browser but with inferior tooling". This remix thing looks like "let's rewrite React in React but with even more inferior tooling" (but I could be wrong, haven't actually given it a chance).
The vast majority of projects I've worked on have been small projects, using big project technology.
Big frameworks (and here I'll speak more to enterprise react) make sense when you have at least one person it is whose fulltime job is be a sort of npm and tooling sysadmin. When you don't, and there's a small handful of you, it's heart-breaking when you all have to stop flying to perform arduous maintenance on your 747 you're ill-equipped to operate, instead of making progress in your cessna.
I don't think it's in denial about being a framework, it's meant as '[groan] not another framework' self-deprecation. (There's an exclamation mark in the original title that's stripped here.)
The reason is that micro frameworks give you more flexibility and in large projects this is gold since you have to deal with so many requirements and multiple stakeholders. In large projects having to do more things "manually" is actually a good thing for this reason. It is likely that you have a large team so in terms of work required it's not going to impact you that much. You can still use libraries for the various things the framework lacks, e.g. it's not like you have to build authentication from scratch, but at least being modular gives you freedom to swap one library for another.
On the other hand whenever I worked in small teams or solo I have been highly appreciative of frameworks like Django that have "batteries included" and let me get things done quickly and efficiently.
It's true what you say "A field of infinite possibilities seems like a great idea, but you quickly realize it's actually a sea of infinite decisions." but this is more of a problem if you are working solo or in a small team, whereas if you have a large team you can put different minds onto different problems/features...
(Edit: grammar)
A more accurate way of thinking about it, IMHO, is to look at how homogeneous the project is. A project can be very very large, but be entirely CRUD forms, and Rails could fit like a glove. But on the other hand, a project could have predominantly "curveball" features (maybe it simultaneously has a real time chat component, twilio integration, newsletter emails, periodic 3rd party data imports, print-to-pdf, etc).
This is a very good point. I tend to take as a given the a highly homogeneous project is always a smaller/simpler one, and that a heterogenous one is always a large project with a large team... but thinking about it, this is not true at all, in fact I can think about some very large projects that don't do many different things, and I can think about some smaller projects I've worked on that are a bit of a Swiss Army knife.
All of these things are pretty easy to do with Rails and Laravel. I don't see how Flask or express or the home made framework on top of those could make anything of this easier. Other than writing the code yourself and not needing to read documentation (which will be a problem for future maintainers) I don't see any advantage for anyone except the one writing it for the fun of it.
Not my experience at all. The "new requirements" you mention are always about business, not technical. Frameworks like Rails, Django and Laravel solve a pretty good bunch of the technical challenges which, in my experience, are common to the 90% of everything we build in most web based companies.
I've seen this argument of let's use flask/sinatra/express/fastapi because I need the flexibility/it is just a simple service too many times. And every single one ended up in a frankestein mix and match of 10s of other libraries that some developer ( now gone, of course) decided at the time was the best thing in the world until he got bored.
Also, you're not forced to use everything in these frameworks. If you think your application just needs routing, you can also use them and call it a day. If it happens 3 years down the line that you need an ORM, then you have it right there waiting for you.
Imagine that you had to build something where you need to use 90 nails and 10 screws: it's not a good idea to do the job with just a hammer, you should probably have a screwdriver as well.
I wouldn't worry too much about it. High schoolers make me cranky and my parent's generation is completely out of touch. My parents and grandparents felt the same at my age. :)
Which is kind of cool IMHO; this means the core libraries remain the same and then the ecosystem improves around. It's a world of a difference between React early days manual setup, the big advancement that was Create-React-App, and then again some other minor but amazing leaps like esbuild or vitejs. I can setup a fully-featured React app and be productive in seconds, with amazing nice things to have that traditionally had to be manually configured in other languages (linter, transpiler, hot module reload, etc).
Browsers are still stuck in the age of every kilobyte mattering, but we try to use them for 21st century things. Not a reuse friendly environment.
This should be ideally fixed on the browser end I think. React and Vue and all the rest could fly to Google and have a big meeting on what to add to browsers that would make it possible to implement all these frameworks in 1k of code.
With more core language support, maybe we could finally have things like Qt and GTK, mature continually maintained libraries that have everything you need and are just there, without you having to worry about the code size.
I guess what I'm asking is, what could the web be if we take a step back and re-evaluate javascript at all instead of just the frameworks that rely on JS?
Your suggestion is like trying to make an F1 car from a Diesel locomotive.
There should be another app, with an altogether different protocol to suit current needs because clearly, we are going to end up with browsers as Operating systems.
Browsers as OSes work fine, aside from the fact that all the advanced features aren't real standards, and everyone other than Google tries to kill them, so you can never be sure what's going to get deprecated later.
Plugins are no longer a thing except for the mostly useless extensions that are only a few steps above a bookmarklet.
As far as I'm concerned,HTML is the best thing we have ever had to represent basically anything that goes on a screen, but HTTP isn't great for some use cases, mostly because of TLS.
Beaker Browser is making a good effort, but I don't really consider any web technology usable till it has mobile support, and I don't like Hypercore's use of append only logs instead of being truly mutable-first.
Modern React development doesn’t deal with these things much not because devs don’t learn web APIs but because most projects use various component libraries that abstract web APIs from devs. You as an app developer do a lot more work to glue components together to achieve the desired behavior and you mostly deal with data management.
I don’t say Remix is bad, it’s an impressive piece of technology for building interactive UIs that tries to blend server side and browser side of web in a neat package, quite successfully I must say! It’s very pleasant to work with, not hard to get into, and I personally haven’t found any big drawbacks. I’d recommend it for all sorts of projects!
But this whole “we do plain web APIs” marketing angle is IMO strange and misleading. Remix is a set of APIs on top of React, you will be building React apps with it, with JSX, hooks and everything else. It’s NOT a vanilla web, far from it.
You would be surprised
Th post links to tutorial, whose first line of actual code is:
import { Link } from "remix";
<Link to="/posts">Posts</Link>
1. This is not the web2. This is not transferrable knowledge
I've skimmed through the tutorial and I fail to see anything in there that "actually teaches you web". It's a bunch or same old React, with same old React abstractions. Not that those abstractions are bad. They are just falling short of what Remix's heavy-handed marketing promises.
Regarding frameworks in general, the common lament is that it's all churn with no progress. In my experience this certainly hasn't been the case. It was much easier to work with jQuery than with the old web APIs, and it's light years easier to work with React than with jQuery or some of the older frameworks like Backbone and Ember. Each step built upon the previous one and unlocked a completely new set of capabilities.
Isn't React Router one of the projects that are famous for completely changing their API for every single version they've released (basically)? Sure, they got a lot of training to perfect designing APIs I guess, but at one point you get frustrated of the constant churn, and the authors neglect of stability.
> We want your experience with Remix to transfer to web development generally.
But then, you opened the quickstart tutorial[1], and the first bit of mark-up is:
<Link to="/posts">Posts</Link>
Uh... okay. Not only is this not how you create links in HTML, but it also repurposes an element that actually does exist in HTML[2] for a completely different purpose. Of course, as to not conflict with that element, I now have to remember to type the L in uppercase, which is another aspect that doesn't carry over to HTML either.It seems the amount they're willing to reinvent is limited to JavaScript.
[1] https://remix.run/docs/en/v1/tutorials/blog [2] https://developer.mozilla.org/en-US/docs/Web/HTML/Element/li...
You can of course use regular <a> links and navigate to a new page every time.
I feel it would be doable for a framework to determine which links should be client-side routed versus not. Or, failing that (or in conjunction with it), provide a way for developers to indicate that information, without reinventing a cornerstone of the web and HTML mark-up from scratch.
I dont know what it is about some devs aversion for HTML.
But a anchor with a data attribute should more than suffice rather than creating over-engineered abstractions.
But then again, not many devs even read the HTML docs.
Also, Remix is for React developers. It's expected you will use JSX, components, etc.
Personally I have a toy client-side router for Svelte. Links that need to trigger client-side navigation simply use a Svelte action:
<a href="/" use:link>Home</a>
I think that is worse. Replacing a core html element behind the scenes to do a `history.pushState` is like to monkey patching. This way you can still use <a> elements and everything will work just fine, or you can very deliberately use a <Link> element if you want the extra functionality it provides.
Same as with the <form> element which will work just fine in Remix as if it was a 2005 PHP project. Or you can use Remix‘s <Form> component which does all the "AJAX" magic behind the scenes that you'll spend two weeks adding to your 2005 PHP project.
Well that gets a big LOL from me. React goes out of its way to eliminate any awareness or interaction with real DOM APIs, and tends to abstract away all kinds of things that are actually straightforward using native JS APIs. Heck, we're only _just now_ perhaps-maybe-hopefully getting true support for web components and they've been around for years.
If you want to use a reactive view library that actually helps you learn about vanilla APIs, try Lit. Or drop down a level and check out Stimulus.
Ah yes. The library that has its own string-based DSL surely "helps you learn about vanilla APIs"
The worst part is that there are millions of github projects that are abandoned, obsolete, uncompilable, unworkable, broken etc. Meanwhile you can still find every kind of widget in jqueryscript.net and it works! Seriously, screw more frameworks, javascript programming is fundamentally broken and no amount of frameworking or godawful constructs will fix that basic fact. After dabbling a bit with 'modern' javascript i m convinced there's a mass epidemic of masochism in the community.
And in the meanwhile browser development is progressing at snail-pace. It's 2022 and we still have to deal with unfinished implementations of ubercomplex things like webrtc.
For a frigging router. With lots of things like "we renamed this or that option or component for literally no reason"
Can see how 1 year from now it is a totally different thing impossible to update without rewriting everything because they've got a new idea.
Pretty cool!
More fitting would have been to have two elements next to each other, one "Remix" that takes you to the landing page, and one "Blog" that takes you to the index of the blog.
Rich Harris (creator of Svelte) has actually been introducing new features to SvelteKit inspired by Remix.
https://github.com/sveltejs/kit/issues/3533
https://github.com/sveltejs/kit/issues/3532
A lot of people in this thread are having weird opinions because they don't really understand the context of Remix. The point of Remix is that it facilitates SSR + hydration + progressive enhancement full stack dev in the most efficient way possible regarding DX. Network wise it's also much more efficient than Next, which is the predominant framework in this space.
Of course if you just want to spit out HTML from your server, Remix would be a pretty stupid choice. In part because React's render to string is very slow, but also because there are already very mature options to do that (Rails, Django, Laravel, etc).
Because Remix goes out if the way to never describe what it actually does.
> The point of Remix is that it facilitates SSR + hydration + progressive enhancement full stack dev in the most efficient way possible regarding DX.
See, if this was written on Remix's website, or in the blog post we're discussing, there would be significantly fewer people "missing the point".
My company is building a B2B ordering system. We take reservations and store fulfillment details with some email and SMS functionality bolted on to a web interface; at least for now it’s a simple business CRUD app. We chose to use Vue for the frontend and Python REST APIs on the backend. And it has been thoroughly frustrating to just ship our MVP, because when I look into our frontend codebase, more than half of it is a bunch of API calls, state management, authentication, and error handling that honestly does not provide much value to the product that we’re offering. I half wish that we had built this in Rails or Django.
Except, we are geospatial-enabled and have a killer interactive map view that powers this whole thing. And it’s not just a single asset-tracking view, but this map component is going to be embedded in several places across the app. And when you zoom, pan, or search the relevant data on screen is updated. I wouldn’t dare try to build this in anything other than one of the big 3 SPA frameworks today.
Why do I have to choose between a traditional app with poor ergonomics for developing frontend JS, and a clunky SPA that reinvents everything the browser has gotten good at in the last 20 years? Remix is a hybrid and I think they are on to something really great here. I can write my server side models and controllers as in days of yore and pass them straight to a renderer that happens to be full blown React + React Router that does as many fancy interactive things on the frontend as I wish once the page is hydrated.
I think it’s easy for backend devs to discount how nice it is to use JSX across the stack if they’re used to a templating language and writing JS sprinkles to manipulate the DOM. And it’s easy for frontend devs to discount how much extra work it is to create an API when your team is only using it internally for a first-party app, because you need APIs for SPAs. But once you realize that you can eliminate these entire bodies of work (manipulating the DOM and writing an unnecessary API), you get the best of both worlds and everything about complicated web dev today feels so achievable.
Even if it’s early days yet, and Remix can’t hold a candle to comprehensive frameworks like Rails, this is much more than just Sinatra or Flask written in JS. I’m seriously excited about where Remix is headed and I’m rooting for these guys all the way.
We would give it credit if Remix actually told us what they are trying to do. Instead we see very heavy-hanvded marketing claiming nothing short of a revolution and failing.
Authentication and error handling are deal breakers, hence very valuable for any paid product.
API calls and state management can be offloaded via libraries. However, they too are essential part of App. Just because they are not sexy or in business domain does not mean that they do not add any value
You don't. The same JavaScript is not 20 year's ago JavaScript, PHP is not 20 year's ago PHP, etc, etc.
Not doing an SPA doesn't mean form POSTs for a like button reloading the whole page or doing jQuery spaghetti. MVC and server side templates rendering has come a long way too.
Some technologies that would make your reservation system trivial to implement with this approach:
- Hotwire (Rails). See https://hotwired.dev/.
- Livewire (Laravel). See https://tallstack.dev/.
- Unpoly (fw agnostic). See https://unpoly.com/
and there are many others.
The caveat here is that you need an open minded engineering team that are happy with using programming languages as tools to build something and not js/python/elixir fanatics which can't touch anything which is not js/python/elixir/etc.
A Nodejs and React based full stack framework with DSL magic. It does progressive enhancement is optimized for partial data fetching and UI updates.
Well i don't fully agree, you still have to learn react/JSX. But they still use the platform lot more than most other solutions(next, react, angular)
They use about the same amount.
I've thought a lot about the idea of transferable knowledge, and my feelings on it have matured a bit over the years.
The premise of the article is that web technologies are transferable knowledge because they underlie helper abstractions, and yes, you're much more likely to gain a higher appreciation of something like FormData if you look at the MDN docs than if you look at the axios docs. But also, that's kinda beside the point if the idiomatic way to do HTTP requests in React has a different API than in Angular.
You could argue that despite the superficial API differences, what is transferable is the understanding of the platform itself: what is CORS, what is CSRF, what are HTTP headers, what is idempotency in the context of HTTP, etc. Learning the standard Request API doesn't necessarily teach any of that any more than learning axios' API. But knowing the platform lets you feel your way around new framework APIs.
Another example: the naked history.pushState API is frankly horrendous to work with. Who wants to think about state machines and mess with scroll positions manually? Routers, on the other hand, are present in pretty much every self-respecting framework, and while their APIs don't always map 1:1 among themselves, the concept of declarative routing is transferable knowledge, because that's what every framework does. That's the "meta".
So I think of transferable knowledge along two axes:
- the first axis is how much can the framework get out of the way of learning the platform. Can I easily figure out what API translates to history.replaceState? Can I easily figure out which API maps to the `credentials` field for a CORS-enabled endpoint? Can I easily reason about CSRF tokens? Can I tell the framework to just take a hike and access the underlying API directly?
- the second axis is how much the framework conforms to developer expectations. How much does a framework conform to the "meta" of declarative views and routers, state and error propagation, etc, and how much is gained or lost by breaking away from mainstream patterns.
There's also something to be said about the emergence of emulation of transferable knowledge. The biggest example of this is Svelte, which looks a lot like "plain vanilla JS", but it achieves this via some non-trivial compilation, which sometimes leaves gaping abstraction holes like the `list = list` pattern. The transferable knowledge here for a more seasoned developer is not so much the basics of JS, but the understanding of how reactivity models are implemented. But this may or may not be the level of knowledge that is relevant for you.
It will soon fade away into the funnel of the web development history; just like its many other brothers before/after it.