Building a Currency Converter App with React and TailwindCSS

Chirag TyagiChirag Tyagi
4 min read

Introduction

Hey folks! ๐Ÿ‘‹ In this post, I want to share the process of building a Currency Converter web app using React and TailwindCSS. The goal was to create a simple tool that converts one currency to another in real-time using live exchange rates.

Beyond just showing how to build it, I'll walk you through the key concepts, challenges I faced, and what I learned โ€” so if you're learning React, working with APIs, or just love building cool UI/UX, this one's for you!


What Does It Do?

The currency converter allows users to:

  • Input an amount

  • Choose a source and target currency

  • Convert the value instantly using live data

  • Swap the currencies with one click

  • Enjoy a smooth, animated UI with responsive design

All of this is achieved with clean component architecture and a neat user interface.


Project Setup (Step-by-Step)

If you'd like to build along, hereโ€™s a quick setup guide:

1. Create a React App

Using Vite or Create React App (CRA). Here's the CRA approach:

npx create-react-app currency-converter
cd currency-converter
npm install

2. Install TailwindCSS

Follow the official TailwindCSS setup:

npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p

Update your tailwind.config.js file:

content: ["./src/**/*.{js,jsx,ts,tsx}"],

Update index.css:

@tailwind base;
@tailwind components;
@tailwind utilities;

3. Project Structure

src/
 โ”œโ”€โ”€ components/InputBox.js
 โ”œโ”€โ”€ hooks/useCurrencyInfo.js
 โ”œโ”€โ”€ App.js
 โ””โ”€โ”€ index.css

Now you're ready to build your Currency Converter App! and Use TailwindCSS by setting it up with PostCSS or installing it via CDN for quick use.

Key Concepts & Features

1. React Functional Components & Hooks

Reactโ€™s useState and useEffect made managing input, output, and fetching data dynamic and powerful.

const [amount, setAmount] = useState(0);
const [from, setFrom] = useState("usd");
const [to, setTo] = useState("inr");
const currencyInfo = useCurrencyInfo(from);

2. Custom Hook: useCurrencyInfo

A custom hook that fetches the latest exchange rates for the selected currency.

function useCurrencyInfo(currency) {
  const [data, setData] = useState({});

  useEffect(() => {
    fetch(`https://cdn.jsdelivr.net/.../${currency}.json`)
      .then((res) => res.json())
      .then((res) => setData(res[currency]))
      .catch(() => setData({}));
  }, [currency]);

  return data;
}

3. Reusable InputBox Component

This allows you to easily reuse styled input/select fields with props.

<InputBox
  label="from"
  amount={amount}
  currencyOptions={options}
  onCurrencyChange={setFrom}
  selectCurrency={from}
  onAmountChange={setAmount}
/>

4. Swap Functionality

Swap both currency and value on a button click:

const swap = () => {
  setFrom(to);
  setTo(from);
  setAmount(convertedAmount);
  setConvertedAmount(amount);
};

And perform conversion:

const convert = () => {
  setConvertedAmount(amount * currencyInfo[to]);
};

5. Animated Submit Button

Added a smooth hover shrink effect with Tailwind:

<button
  className="w-full bg-blue-600 text-white px-4 py-3 rounded-lg cursor-pointer
             transition-all duration-300 ease-in-out transform hover:scale-x-90 hover:bg-blue-700">
  Convert {from.toUpperCase()} to {to.toUpperCase()}

</button>

6. Handling Background Image with Fallback

If external image fails, fallback to local image:

const [bgImage, setBgImage] = useState(remoteImage);

useEffect(() => {
  const img = new Image();
  img.src = remoteImage;
  img.onerror = () => setBgImage(localFallback);
}, []);

Challenges Faced

  • Dynamic Fetching: Making useEffect update correctly for new currency data.

  • Error Handling: Ensuring UI doesnโ€™t break when API fails.

  • UI/UX Smoothing: Getting the animations right using Tailwind's transition-all and ease-in-out.

  • Image Fallbacks: Preventing a broken look by implementing graceful image fallbacks in JS.


What I Learned

  • Creating custom hooks in React

  • Abstracting UI into reusable components

  • Handling API errors gracefully

  • Working with Tailwind transitions and interactivity

  • Responsive layout techniques with utility-first CSS

  • JavaScript-based image fallback strategy


Future Improvements

  • Add currency trend charts

  • Save recent conversions

  • Support historical exchange rates

  • Improve accessibility and mobile UX

  • Implement dark mode toggle


Tech Stack

๐Ÿ›  Tools & Libraries Used:

  • React (Functional Components + Hooks)

  • TailwindCSS

  • Fawaz Ahmedโ€™s Currency API

  • JavaScript (ES6+)

  • Vite or CRA (Create React App)

  • Vercel or Netlify (Deployment)


Final Thoughts

This app was more than just a currency converter โ€” it was a learning journey! From working with real APIs to enhancing UI with Tailwind, I picked up a lot of practical skills.

If you're building similar projects, I highly recommend trying out:

  • Custom hooks for reusable logic

  • CSS transitions for animations

  • Graceful fallbacks for assets like images

Thanks for reading! Hope this inspires or helps with your own React projects. ๐Ÿ™Œ


You can try out the live version of this app here: ๐Ÿ‘‰ Currency Converter Live Demo


๐Ÿ’ป GitHub Source Code

All the code is available on GitHub if youโ€™d like to explore it, fork it, or contribute: ๐Ÿ‘‰ GitHub Repository


๐Ÿค Connect with Me

I love collaborating and chatting about web development, React, and cool projects. Feel free to connect with me:

Feel free to share feedback, questions, or your own version of this project. Letโ€™s keep learning and building together!!

0
Subscribe to my newsletter

Read articles from Chirag Tyagi directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Chirag Tyagi
Chirag Tyagi

Profile Bio Iโ€™m currently pursuing B.Tech in Computer Science and Engineering at Roorkee Institute of Technology, where I am deeply engaged in learning full-stack development with the MERN stack. My passion for technology drives me to explore and stay updated with the latest advancements in the field. Eager to apply and expand my skills, I am committed to continuous learning and growth in the ever-evolving tech landscape.