6 ms·
The killer upgrade here isn’t ESM. It’s Node baking fetch + AbortController into core. Dropping axios/node-fetch trimmed my Lambda bundle and shaved about 100 m
by farkin88 1y ago
The killer upgrade here isn’t ESM. It’s Node baking fetch + AbortController into core. Dropping axios/node-fetch trimmed my Lambda bundle and shaved about 100 ms off cold-start latency. If you’re still npm i axios out of habit, 2025 Node is your cue to drop the training wheels.
- yawnxyz 1y agonode fetch is WAY better than axios (easier to use/understand, simpler); didn't really know people were still using axios
- Raed667 1y agoI do miss the axios extensions tho, it was very easy to add rate-limits, throttling, retry strategies, cache, logging .. You can obviously do that with fetch but it is more fragmented and more boilerplate
- farkin88 1y agoTotally get that! I think it depends on your context. For Lambda where every KB and millisecond counts, native fetch wins, but for a full app where you need robust HTTP handling, the axios plugin ecosystem was honestly pretty nice. The fragmentation with fetch libraries is real. You end up evaluating 5 different retry packages instead of just grabbing axios-retry.
- hiccuphippo 1y agoSounds like there's space for an axios-like library built on top of fetch.
- lllllllllllll6 1y ago[dead]
- farkin88 1y agoI think that's the sweet spot. Native fetch performance with axios-style conveniences. Some libraries are moving in that direction, but nothing's really nailed it yet. The challenge is probably keeping it lightweight while still solving the evaluating 5 retry packages problem.
- crabmusket 1y agoIs this what you're looking for? https://www.npmjs.com/package/ky https://www.npmjs.com/package/ky I haven't used it but the weekly download count seems robust.
- farkin88 1y agoKy is definitely one of the libraries moving in that direction. Good adoption based on those download numbers, but I think the ecosystem is still a bit fragmented. You've got ky, ofetch, wretch, etc. all solving similar problems. But yeah, ky is probably the strongest contender right now, in my opinion.
- hokkos 1y agoLike axios can do it if you specify the fetch backend, it just won't do the .json() asynchronously.
- tracker1 1y agoI'm actually not a big fan of the async .json from fetch, because when it fails (because "not json"), then you can't peak at the text instead. Of course, you can clone the response, apparently, and then read text from the clone... and if you're wrapping for some other handling, it isn't too bad.
- farkin88 1y agoRight?! I think a lot of devs got stuck in the axios habit from before Node 18 when fetch wasn't built-in. Plus axios has that batteries included feel with interceptors, auto-JSON parsing, etc. But for most use cases, native fetch + a few lines of wrapper code beats dragging in a whole dependency.
- benoau 1y agoaxios got discontinued years ago I thought, nobody should still be using it!
- creatonez 1y agoNo? Its last update was 12 days ago
- reactordev 1y agoYou still see axios used in amateur tutorials and stuff on dev.to and similar sites. There’s also a lot of legacy out there.
- bravesoul2 1y agoAI is going to bring that back like an 80s disco playing Wham. If you gonna do it do it wrong...
- reactordev 1y agohahaha, I see it all the time in my responses. I immediately reject.
- macNchz 1y agoI've had Claude decide to replace my existing fetch-based API calls with Axios (not installed or present at all in the project), apropos of nothing during an unrelated change.
- int_19h 1y agoI had Gemini correct my code using Google's new LLM API to use the old one.
- mcv 1y agoThis is all very good news. I just got an alert about a vulnerability in a dependency of axios (it's an older project). Getting rid of these dependencies is a much more attractive solution than merely upgrading them.
- thewisenerd 1y agoisn't upgrading node going to ba bigger challenge? (if you're on a node version that's no longer receiving maintenance)
- mcv 1y agoNo idea how much compatibility breakage there is, but it's probably going to have to happen at some point, and reducing dependencies sounds worth it to me.
- looshch 1y agowhat about interceptors?
- ramesh31 1y agoInterceptors (and extensions in general) are the killer feature for axios still. Fetch is great for scripts, but I wouldn't build an application on it entirely; you'll be rewriting a lot or piecing together other libs.
- franciscop 1y agoAs a library author it's the opposite, while fetch() is amazing, ESM has been a painful but definitely worth upgrade. It has all the things the author describes.
- farkin88 1y agoInteresting to get a library author's perspective. To be fair, you guys had to deal with the whole ecosystem shift: dual package hazards, CJS/ESM compatibility hell, tooling changes, etc so I can see how ESM would be the bigger story from your perspective.
- franciscop 1y agoI'm a small-ish time author, but it was really painful for a while since we were all dual-publishing in CJS and ESM, which was a mess. At some point some prominent authors decided to go full-ESM, and basically many of us followed suit. The fetch() change has been big only for the libraries that did need HTTP requests, otherwise it hasn't been such a huge change. Even in those it's been mostly removing some dependencies, which in a couple of cases resulted in me reducing the library size by 90%, but this is still Node.js where that isn't such a huge deal as it'd have been on the frontend. Now there's an unresolved one, which is the Node.js streams vs WebStreams, and that is currently a HUGE mess. It's a complex topic on its own, but it's made a lot more complex by having two different streaming standards that are hard to match.
- farkin88 1y agoWhat a dual-publishing nightmare. Someone had to break the stalemate first. 90% size reduction is solid even if Node bundle size isn't as critical. The streams thing sounds messy, though. Two incompatible streaming standards in the same runtime is bound to create headaches.
- bikeshaving 1y agoThe fact that CJS/ESM compatibility issues are going away indicates it was always a design choice and never a technical limitation (most CJS format code can consume ESM and vice versa). So much lost time to this problem.
- deleted 1y ago[deleted]
- vinnymac 1y agoUndici in particular is very exciting as a built-in request library, https://undici.nodejs.org https://undici.nodejs.org
- farkin88 1y agoUndici is solid. Being the engine behind Node's fetch is huge. The performance gains are real and having it baked into core means no more dependency debates. Plus, it's got some great advanced features (connection pooling, streams) if you need to drop down from the fetch API. Best of both worlds.
- forty 1y agoIt's into core but not exposed to users directly. you still need to install the npm module if you want to use it, which is required if you need for example to go through an outgoing proxy in your production environment
- synergy20 1y agoaxios works for both node and browser in production code, not sure if fetch can do as much as axios in browser though
- pbreit 1y agoIt has always astonished me that platforms did not have first class, native "http client" support. Pretty much every project in the past 20 years has needed such a thing. Also, "fetch" is lousy naming considering most API calls are POST.
- rendall 1y agoThat's a category error. Fetch is just refers to making a request. POST is the method or the HTTP verb used when making the request. If you're really keen, you could roll your own const post = (url) => fetch(url, {method:"POST"})
- catlifeonmars 1y agoI read this as OP commenting on the double meaning of the category. In English, “fetch” is a synonym of “GET”, so it’s silly that “fetch” as a category is independent of the HTTP method
- rendall 1y agoThat makes sense.
- catlifeonmars 1y ago“Most” is doing a lot of heavy lifting here. I use plenty of APIs that are GET
- pbreit 1y agoI was thinking server-side where it's probably 90%+ POST. True, client-side a lot different (node the only player client-side, though).
- deleted 1y ago[deleted]
- tracker1 1y agoNode was created with first-class native http server and client support. Wrapper libraries can smooth out some rough edges with the underlying api as well as make server-side js (Node) look/work similar to client-side js (Browser).
- exhaze 1y agoTangential, but thought I'd share since validation and API calls go hand-in-hand: I'm personally a fan of using `ts-rest` for the entire stack since it's the leanest of all the compile + runtime zod/json schema-based validation sets of libraries out there. It lets you plug in whatever HTTP client you want (personally, I use bun, or fastify in a node env). The added overhead is totally worth it (for me, anyway) for shifting basically all type safety correctness to compile time. Curious what other folks think and if there are any other options? I feel like I've searched pretty exhaustively, and it's the only one I found that was both lightweight and had robust enough type safety.
- farkin88 1y agoType safety for API calls is huge. I haven't used ts-rest but the compile-time validation approach sounds solid. Way better than runtime surprises. How's the experience in practice? Do you find the schema definition overhead worth it or does it feel heavy for simpler endpoints?
- _heimdall 1y agoI always try to throw schema validation of some kind in API calls for any codebase I really need to be reliable. For prototypes I'll sometimes reach for tRPC. I don't like the level of magic it adds for a production app, but it is really quick to prototype with and we all just use RPC calls anyway. For procudtion I'm most comfortable with zod, but there are quite a few good options. I'll have a fetchApi or similar wrapper call that takes in the schema + fetch() params and validates the response.
- tanduv 1y agoI never really liked the syntax of fetch and the need to await for the response.json, implementing additional error handling - async function fetchDataWithAxios() { try { const response = await axios.get('https://jsonplaceholder.typicode.com/posts/1'); console.log('Axios Data:', response.data); } catch (error) { console.error('Axios Error:', error); } } async function fetchDataWithFetch() { try { const response = await fetch('https://jsonplaceholder.typicode.com/posts/1'); if (!response.ok) { // Check if the HTTP status is in the 200-299 range throw new Error(`HTTP error! status: ${response.status}`); } const data = await response.json(); // Parse the JSON response console.log('Fetch Data:', data); } catch (error) { console.error('Fetch Error:', error); } }
- farkin88 1y agoYeah, that's the classic bundle size vs DX trade-off. Fetch definitely requires more boilerplate. The manual response.ok check and double await is annoying. For Lambda where I'm optimizing for cold starts, I'll deal with it, but for regular app dev where bundle size matters less, axios's cleaner API probably wins for me.
- hn_throwaway_99 1y agoAgreed, but I think that in every project I've done I've put at least a minimal wrapper function around axios or fetch - so adding a teeny bit more to make fetch nicer feels like tomayto-tomahto to me.
- jedwards1211 1y agoYou’re shooting yourself in the foot if you put naked fetch calls all over the place in your own client SDK though. Or at least going to extra trouble for no benefit
- Tokumei-no-hito 1y agowhy don't they just set those as options { throwNotOk, parseJson } they know that's 99% of fetch calls, i do t see why it can't be baked in.
- TheRealPomax 1y agoThose... are not mutually exclusive as killer upgrade. No longer having to use a nonsense CJS syntax is absolutely also a huge deal. Web parity was "always" going to happen, but the refusal to add ESM support, and then when they finally did, the refusal to have a transition plan for making ESM the default, and CJS the fallback, has been absolutely grating for the last many years.
- 8n4vidtmkvmk 1y agoEspecially since it seems perfectly possible to support both simultaneously. Bun does it. If there's an edge case, I still haven't hit it.
- andai 1y ago16 years after launch, the JS runtime centered around network requests now supports network requests out of the box.
- snickerdoodle12 1y agoObviously it supported network requests, the fetch api didn't even exist back then, and XMLHttpRequest which was the standard at the time is insane.
- 8n4vidtmkvmk 1y agoInsane but worked well. At least we could get download progress.
- CSSer 1y agoYou can get download progress with fetch. You can't get upload progress. Edit: Actually, you can even get upload progress, but the implementation seems fraught due to scant documentation. You may be better off using XMLHttpRequest for that. I'm going to try a simple implementation now. This has piqued my curiosity.
- pests 1y agoSniped
- kookamamie 1y agoNerd
- CSSer 1y agoMainly by the fact that all the LLMs were saying it's not possible in addition to GP, and I just couldn't believe that was true...
- CSSer 1y ago
- hliyan 1y agoThere has to be something wrong with a tech stack (Node + Lambda) that adds 100ms latency for some requests, just to gain the capability [1] to send out HTTP requests within an environment that almost entirely communicates via HTTP requests. [1] convenient capability - otherwise you'd use XMLHttpRequest
- bilalq 1y ago1. This is not 100ms latency for requests. It's 100ms latency for the init of a process that loads this code. And this was specifically in the context of a Lambda function that may only have 128MB RAM and like 0.25vCPU. A hello world app written in Java that has zero imports and just prints to stdout would have higher init latency than this. 2. You don't need to use axios. The main value was that it provides a unified API that could be used across runtimes and has many convenient abstractions. There were plenty of other lightweight HTTP libs that were more convenient than the stdlib 'http' module.
- PartiallyTyped 1y agoOn init lambda funcs run a full core, but on invoke the 128MB run at 1/20 core.
- jedwards1211 1y agoThis has been the case for quite awhile, most of the things in this article aren’t brand new
- pjmlp 1y agoIt kills me that I keep seeing axios being used instead of fetch, it is like people don't care, copy-paste existing projects as starting point and that is it.
- bilekas 1y agoMaybe I'm wrong and it's been updated but doesn't axios support progress indicators out of the box and just generally cleaner? That's said there are npm packages that are ridiculously obsolete and overused.
- pjmlp 1y agoMay be, however I seldom see those things being used, it is always just request response kind of workflow.
- moogly 1y agoWith node:fetch you're going to have to write a wrapper for error handling/logging/retries etc. in any app/service of size. After a while, we ended up with something axios/got-like anyway that we had to fix a bunch of bugs in.
- larsnystrom 1y agoAnd AFAIK there is still no upload progress with fetch.