You don't need Axios, well, for most use cases. The web is maturing, and the days of Axios are ending.
Why we needed Axios
For newcomer...
Some comments have been hidden by the post's author - find out more
For further actions, you may consider blocking this person and/or reporting abuse
You may not need axios, just like you do not need any luxuries in life.
But why would you avoid
axios
?Axios provides a much better api / dev experience calling http endpoints. That's a plus.
What are the downsides, except bundle size ?
axios bundle size is 57 kB -> 21.8 kB (gzip)
bundlejs.com/?q=axios%401.5.1
Hi @adaptiveshieldmatrix
Thanks for your feedback. I agree with you on the DX part.
I know the article says "axios" but it's really about not bringing in dependencies unless the DX is so poor you'd throw your laptop out if you don't bring in a library.
Picking on
axios
one more time: axios have three dependencies, one of which is form-data. We don't need this dependency in the browser because the browser natively supports form data, and you also don't need it in nodejs from node 18+. Form data also have 3 other dependencies that also have their dependencies. The dependency tree goes on and on, and at any point, one of the maintainers might decide to hit the kill switch on the project. For example, form-data's last update was three years ago, but it currently has 113 open issues.All that dependency when what most(not all) web applications out there do is fetch data and map to JSX or render to HTML, listen to events, submit data, update state, and repeat.
1.
I think its okay for library to not get any updates if the protocol (multipart, like in the case of form-data) is stable.
Do all libraries have to release new versions just for appearance sake?
Axios has many issues listed
github.com/axios/axios/issues?q=is...
but no bugs (mostly feature requests and questions about edge cases)
and seems very safe / stable to use.
I can understand your strife to reduce dependencies, but that are the alternatives ? Write http data fetching libraries yourself
or suffer poor DX because of raw XMLHttpRequest / fetch.
2.
I have looked a bit more at http client libraries
Here seems to be a good comparison
github.com/sindresorhus/got#compar...
Following your main grip against axios -> ky seems to be the next best choice for http clients in the browser
github.com/sindresorhus/ky
With a bundle size of only 9.12 kB -> 3.23 kB gzip
https://bundlejs.com/?q=ky%401.1.0&treeshake=%5B*%5D
thanks. Would check the links out
One reason to avoid axios, difficult to handle errors.
How is it more difficult to handle than fetch?
You can even overwrite/define then it throws errors
pipedream.com/community/t/faq-how-...
it's not about when it throws, it's how it handles errors. It hides the response in error.response.data, which becomes a big issue when dealing with typescript.
How is accessing the response with
error.response.data
in typescript a big problem?When using
asyn/await
you loose all types, so you have to doAnd I just don't like writing
error.response?.data?.whatever
in general. I generally prefer dealing withResponse
.And there's no way to conditionally tell axios to not parse responses. One big reason to not use axios is because of the all or nothing behaviour. You have build a client for each scenario (which is unrealistic)
You can type axios, example:
await axios.post<EventType[] | { errorMessage: string }>(urlApiCmdPublic, cmd)
so I would not count that as a downside. Fetch in comparison does not have any types at all.
"no way to conditionally tell axios to not parse responses" - that's a fair point,
but its relevant only if using some non-http/rest APIs - which to be fair should be pretty rare.
I agree with you, that
axios
is mostly designed to consume http/rest apis with good developer experienceand having the niche use-case of calling lower level binary apis is best served using lower level tools like
fetch
.await axios.post<EventType[] | { errorMessage: string }>(urlApiCmdPublic, cmd)
only works for non-error responses.Not exactly true, you get a
Response
which makes sense. And then you can convert to json and do validation i.e using zodschema.parse(await response.json())
to get a concrete type. Which is a much better approach than what axios offersI would be very interested in seeing exactly what you refer to. What am I gaining, exactly, for the extra 57kb?
The top things I can think of:
json()
(in comparison to fetch) to get the dataWith the release of
fetch
this list got much shorter...I think I'm slowly coming around to using fetch on the browser as well
I see. I think the author (and I agree) is on the line of "90% of people don't need adapters, don't need base paths or have them covered elsewhere". I think that for 9 out of 10 developers,
axios
is 57kb of "nothing I need".I imagine that the adapters are probably very handy, but are also probably very specific and catered for the minority, not the majority.
So yes, I think you are doing the right thing considering
fetch()
as the primary tool here. If you need interception of request or response, that's something that can be easily done in far less than 57kb.Cheers!
Its size is 13.7 kB gzipped (ESM)
18.8 kB gzipped (UMD, ES5)
Never Mutate Global State
I suggest that mutating global state like this is the opposite of a pro tip:
Now, every single client side request that uses fetch under the hood will not work as expected. You've literally broken every request.
In a commercial setting, you're almost guaranteed to be running some vendor scripts on the client. Things like logging services, tracking and marketing, A|B tests, heat mapping or service integrations. All of these will no longer work as expected if they use the
fetch
API. Not to mention any browser extensions or user scripts that may be loaded on the client...Even the simple action of transforming the response to JSON like this will break any call to
fetch
.Broken Implementation
Just try this example after mutating
global.fetch
:Calling this function will output:
This is incredibly difficult to reason about as these errors are misleading.
In this case, vendors who use
axios
are better off because this mutation doesn't affectXMLHttpRequest
.Use Encapsulation
This is closer to what I would consider a professional approach:
Neither Choice is Superior
The choice between
axios
andfetch
depends on the context of the problem. You've laid out a number of examples that, from your perspective, makeaxios
seem redundant to you. However, your examples actually make a strong case for usingaxios
in a commercial setting to me.As someone who's created some
XMLHttpRequest
implementations by hand, I have similar misgivings to usingfetch
today that I did back then.It really highlights the convenience that
axios
provides. I look at your form examples and I see a lot of additional code that the team has to maintain.Your example has zero dependencies:
This example is less complex, more convenient and less maintenance:
Reinventing the Wheel vs Getting Things Done
I want to reiterate that I don't see any choice as superior to the other before sharing my experience using fetch out of the box in a project.
It almost always ends up with something like this to make a basic request:
Then a stakeholder comes along and adds a new business requirement to fetch something from
resource-b
as well. So the fetch logic is encapsulated:This is the reality that you face when building complex applications with
fetch
. It's a considerable investment to save 23KB on a request.To achieve the same result with
axios
:On Not Mutating Global State
That is an excellent point on not mutating the global state. Thanks for the callout. The main point I was trying to make is to
always encapsulate(wrap)
.In my codebase, it looks something like this.
I'll do an edit sometime during the day to reflect this.
To reinvent the wheel or not to
This topic is very subjective, so I'll have to answer subjectively. Having written and made HTTP requests in another language (i.e. go and rust) in the past year, returning to
fetch
didn't seem like a lot of work.Arguably, many of the JS libraries out there are reinventing the wheel for better or worse.
At the end of the day, it's up to your team to decide how much re-invention is too much reinvention.
On whether one is superior to the other
This is not a subjective one, so here are my plus for
fetch
I used to have this opinion that
axios
wasn't worth using overfetch
. But lately I've found that it has some nice middleware features thatfetch
doesn't have. So I'd say it isn't worth throwing out just yet.I guess it all just depends on how you use it in the end. If you're not using some of those special
axios
features then by all means don't add it as a dependency to your project when you can just usefetch
.I completely agree with you that some large-scale projects especially the ones that require heavy file uploads will still benefit much from axios.
Earlier this year, I took over a project and I was kindof irritated by the fact that the original developer used just fetch. I thought it would end up being a problem for me along the line but after many months, I completely stopped missing axios. This is what inspired this article.
Ok yeah that makes a lot of sense! Thanks for sharing :)
I followed your recommendation and took a look at
undici
There is a long discussion about fetch performance
github.com/nodejs/undici/issues/1203
For example in this benchmark (updated about a month ago)
github.com/silverwind/fetch-bench
undici: 2966ms
axios: 2429ms
-> axios is faster than undici
The increased bundle size of axios (57 kB -> 21.8 kB gzip) is not an issue on the server (only in the client/browser)
I would say, that it is a contested point, which of the 2 libraries is better
axios
orundici
Interesting. I'm watching that space now to see how it evoves overtime. Thanks for sharing. We learn everyday.
Hey thanks, nice and concise explanation. I am a proponent of ditching all JS Libraries for most use cases. Without JQuery or Axios we can now do everything in Plain Vanilla JS. Fetch is definately the way to go. Also I ditched my databases too and am now all serverless using json for my small use case and non relational data sets. PS, I am not a student so can get away without using React or Node. I use only small apps for everything, like AWS Lambdas for example. Everything as a Service !!
Timeouts are not only backend related. We could have a connection timeout without even reaching the backend, or a receive timeout when the network connection drops.
Thanks but Axios saved one of my projects. However you bring up a valid point with Fetch giving you the option to not have any dependencies in your project. I had issues with Fetch before but I will give it a crack again sometime.
Thanks Matthew. Contrary to what it might sound like, I'm not advocating against using axios. I'm just raising awareness that we now have this cool thing called fetch and it's getting really good. 😊
Yes, i also often think it is much easier to wrap the fetch api than learning the api of axios.
The AbortSignal Timeout was new to me 👌
But Axios is more then getting data, it’s also well structured Error handling and developer experience (DX)
I’m a big fan of axios, but I am not offended by this 😆 very nice write up. 🙌🏻
Never do this
That's a terrible advice
will use axios.
🎉
Fetch is just a tiny piece of a cake of what Axios can so. You don’t need it really when you just need to request or send simple data. But it is useless for a huge REST application, for instance
“ Unfortunately”, this word means too much, uploading and downloading are very common in real-world R&D, and it may be a loss because of dependencies but efficiency.
And no one say that axios can be used in node the same way as in browser