This case study demonstrates the use of Codemod2.0 for migrating from Axios to Fetch. Codemod2.0 utilizes a combination of deterministic engines like ast-grep and large language models (LLMs), requiring access to an OpenAI API key (BYOM: bring your own model). This approach offers a semi-automated migration process that can be particularly beneficial for developers considering the shift from Axios to Fetch. There are alternative approaches, each with its own strengths and weaknesses, which you can learn more about here.


Why Migrate from Axios to Fetch?

With the Fetch API now supported by 97.25% of users' browsers globally, many developers are moving away from older libraries like Axios, similar to the transition from jQuery. Here are some key benefits of adopting Fetch:

  • Reduced Dependencies: Fetch is built into the browser, eliminating the need for external libraries.
  • Enhanced Error Handling: Fetch provides more consistent error handling mechanisms.
  • Cross-Browser Compatibility: Fetch works seamlessly across different browsers and server environments.
  • Smaller Bundle Sizes: Removing Axios can reduce the overall size of your web application bundle.

Axios to Fetch Migration Steps

Migrating from Axios to Fetch requires several steps for a smooth transition:

Step
Axios
Fetch
Basic Request Setup
Simplifies syntax for common use cases and automatically handles JSON data
Requires more configuration and manual handling of JSON data. You need to parse JSON responses explicitly
Handling Defaults
Allows setting default headers, base URLs, and timeouts globally
Requires manual setup for headers and other configurations in each request or by creating a wrapper function to handle these settings
Interceptors
Provides built-in support for request and response interceptors to modify requests or handle errors globally
Lacks built-in interceptor support, so you need to implement custom middleware or wrapper functions to achieve similar behavior
Error Handling
Automatically rejects promises for HTTP errors and provides detailed error messages
Requires manual checking of response status and rejection of promises. You need to write custom error-handling logic
Cancellation
Supports request cancellation through CancelTokens
Uses AbortController for request cancellation, which requires additional setup and management
Transforming Requests and Responses
Includes built-in methods for transforming requests and responses
Requires manual transformation, often necessitating additional parsing and processing logic
Instance Creation
Allows creating instances with custom configurations
Does not support instance creation natively, so you need to implement factory functions to achieve similar functionality

Manual migration can be tedious and error-prone, especially in large codebases. Codemod2.0 can automate much of this process, making it more efficient and less error-prone.

Migration Process with Codemod2.0

Identifying Axios Usages:

Using ast-grep, we can quickly locate most occurrences of Axios in the codebase. Here are some common Axios patterns (also, see ast-grep playground):

import axios from 'axios'
const response1 = await axios.get(url, options)
const response2 = await axios.post(url, options).then(...)
const response3 = await axios(options).then(...).catch(...)

Patterns to Match:

const axiosPatterns = [
{ pattern: "axios($$$_)" }, // axios()
{ pattern: "axios.$_($$$)" }, // axios.get(...)
{ pattern: "axios.$_($$$).$_($$$)" }, // axios.get(...).then(...)
{ pattern: "axios.$_($$$).$_($$$).$_($$$)" }, // axios.get(...).then(...).catch(...)
{ pattern: "axios.$_($$$).$_($$$).$_($$$).$_($$$)" }, // axios.get(...).then(...).catch(...).finally(...)
];

Codemod Instructions:

Once we found all the occurrences, we can ask LLM to replace axios with fetch with specific instructions:

const prompt = `
You are migrating from axios to fetch.
Ignore axios.create() and axios.all() as fetch doesn’t have these APIs.
Here is a general pattern to replace axios with fetch:
1. Replace axios.anyFunction(url) with fetch(url, options) and await it.
2. if response.ok is false, throw an error.
3. Get the response by calling response.json() or response.text() or response.blob() or response.arrayBuffer().
4. To be compatible with axios, you need to need to set result variable to { data: await response.json() }.
5. Infer the type of result variable from context and apply type to resulve variable { data: await response.json() as SomeType }.
Use AbortSignal to replace axios timeout option.
For example,
axios.get(url, { timeout: 5000 })
can be replaced with
fetch(url, { signal: AbortSignal.timeout(5000) })
`;

Results of Codemod2.0

After running the codemod on our own Codemod monorepo:

npx codemod@latest axios/fetch --OPENAI_API_KEY=$OPENAI_API_KEY

Number of replacements: 16

Completely Automatic Migrations: 7/16 (43.75%)

  • LLM correctly inferred types: 5/16 (31.25%)

Migrations Requiring Small Fixes: 6/16 (37.5%)

  • Examples include adding types or fixing minor typos.

Migrations Requiring Large Manual Changes: 3/16 (18.75%)

Overall, 81.25% of cases were migrated either completely automatically or with minor fixes.

Conclusion

Codemod2.0 significantly reduces the effort required to migrate from Axios to Fetch, automating a substantial portion of the process. While some features specific to Axios, such as interceptors, instance creation, and request transformations, still require manual handling, the automated approach provided by Codemod2.0 proves to be highly effective for most common use cases. For larger commercial codebases needing more reliability and coverage, or for fully delegating the migration, our certified experts are available to assist.

For more information and to get started with your migration, please contact us.