RORK LABJP
TOOLING — Rork's developer repos keep moving: rork-xcode was updated on July 16, rork-device on July 15, and rork-plist on July 13OPUS46 — Claude Opus 4.6 is live in Rork, and Rork Max is built to assemble apps on top of Claude CodeSIM — A cloud iOS simulator runs in the browser, with one click to install on a device and two clicks to publish to the App StoreMAX — Rork Max emits pure Swift rather than React Native, reaching iPhone, iPad, Apple Watch, Apple TV, Vision Pro, and even iMessageNATIVE — That opens up HealthKit, ARKit and LiDAR, NFC, Dynamic Island, Live Activities, 3D through Metal, and on-device inference with Core MLSEED — Rork raised a $15M seed led by Left Lane Capital, with Peak XV and a16z Speedrun joining the roundTOOLING — Rork's developer repos keep moving: rork-xcode was updated on July 16, rork-device on July 15, and rork-plist on July 13OPUS46 — Claude Opus 4.6 is live in Rork, and Rork Max is built to assemble apps on top of Claude CodeSIM — A cloud iOS simulator runs in the browser, with one click to install on a device and two clicks to publish to the App StoreMAX — Rork Max emits pure Swift rather than React Native, reaching iPhone, iPad, Apple Watch, Apple TV, Vision Pro, and even iMessageNATIVE — That opens up HealthKit, ARKit and LiDAR, NFC, Dynamic Island, Live Activities, 3D through Metal, and on-device inference with Core MLSEED — Rork raised a $15M seed led by Left Lane Capital, with Peak XV and a16z Speedrun joining the round
Articles/Dev Tools
Dev Tools/2026-05-05Beginner

Build a Real-Time Currency Converter App with Rork — API Integration, Home Screen Widget, and Error Handling

A practical tutorial for building a currency converter app from scratch with Rork. Covers ExchangeRate-API integration, home screen widget support, and handling common errors gracefully.

Rork515app development40external API2currency converterwidgetReact Native209tutorial20

A currency converter is one of the best first projects to build in Rork. It looks simple on the surface, but it covers the full range of skills you need — fetching from an external API, managing state, designing a clean UI, and handling errors gracefully.

When I was first working through what it means to actually ship an app, projects at this scale turned out to be the most efficient way to learn. Here's how to build one from scratch, including a home screen widget.

What We're Building

The finished app will include:

  • Live exchange rates for major currencies (JPY / USD / EUR / GBP / CNY)
  • Instant conversion as you type
  • A home screen widget (iOS only) showing key rates
  • Error fallback with retry when the network is unavailable

The widget requires Rork Max, but the main app works on the free Rork plan.

Step 1: Set Up ExchangeRate-API

For exchange rate data, we'll use ExchangeRate-API (https://www.exchangerate-api.com/). The free plan gives you 1,500 requests per month, which is more than enough for a personal project.

Sign up, copy your API key from the dashboard, and note the request format:

GET https://v6.exchangerate-api.com/v6/{YOUR_API_KEY}/latest/USD

A successful response looks like this:

{
  "result": "success",
  "base_code": "USD",
  "conversion_rates": {
    "JPY": 153.42,
    "EUR": 0.9187,
    "GBP": 0.7892,
    "CNY": 7.2341
  }
}

Step 2: Generate the Main Screen in Rork

Paste the following prompt into Rork. Keeping the scope focused — one screen at a time — produces cleaner code than asking for everything at once.

Create the main screen for a currency converter app.

Requirements:
- A picker at the top for the base currency (USD / EUR / JPY / GBP / CNY)
- A numeric input field for the amount
- A list showing converted values in all five currencies
- Skeleton loading state while fetching
- An error state with a "Retry" button

Design:
- System font, clean card-based layout
- Full light/dark mode support

Once the screen is generated, add the API fetch function by prompting Rork to integrate it:

// Fetch live exchange rates
// Store the API key in EXPO_PUBLIC_EXCHANGE_API_KEY (environment variable)
const fetchExchangeRates = async (baseCurrency: string): Promise<Record<string, number>> => {
  const apiKey = process.env.EXPO_PUBLIC_EXCHANGE_API_KEY;
 
  if (!apiKey) {
    throw new Error('API key is missing. Add EXPO_PUBLIC_EXCHANGE_API_KEY to your .env file.');
  }
 
  const response = await fetch(
    `https://v6.exchangerate-api.com/v6/${apiKey}/latest/${baseCurrency}`
  );
 
  if (!response.ok) {
    throw new Error(`API error: ${response.status}`);
  }
 
  const data = await response.json();
 
  if (data.result !== 'success') {
    throw new Error(`Fetch failed: ${data['error-type'] ?? 'Unknown error'}`);
  }
 
  return data.conversion_rates;
};

Why use an environment variable? Hardcoding the API key directly in your source code exposes it if you ever push to GitHub. Add it through Rork's Settings > Environment Variables instead.

Step 3: State Management and Live Conversion Logic

For real-time conversion as the user types, a combination of useEffect and useMemo works well. Prompt Rork to add this structure:

Add the following state to the currency converter component:

- baseCurrency (string): currently selected base currency
- inputAmount (string): the amount the user typed (keep as string)
- rates (Record<string, number>): fetched exchange rates
- isLoading (boolean): true while fetching
- error (string | null): error message if fetch fails

Calculate converted values with useMemo so they only recompute
when baseCurrency or rates change.

One thing worth double-checking in the generated code: inputAmount should be stored as a string, not a number. Storing it as a number breaks the input when the user types something like 0. or 0.05 — the decimal gets dropped mid-input. Keep the raw string and parse it only when calculating the result.

Step 4: Three Errors You'll Probably Hit

1. Conversion rates come back as undefined

The keys in conversion_rates are uppercase currency codes ("JPY", not "jpy"). If your picker emits lowercase codes, the lookup will silently return undefined.

// ❌ Lowercase lookup returns undefined
const rate = rates["jpy"];
 
// ✅ Match the uppercase keys from the API
const rate = rates["JPY"];

2. A failed fetch crashes the app instead of showing an error

Missing error handling around fetch is a common source of crashes. Wrap the call in try-catch and always reflect the error in state:

const loadRates = async () => {
  setIsLoading(true);
  setError(null);
  try {
    const newRates = await fetchExchangeRates(baseCurrency);
    setRates(newRates);
  } catch (err) {
    // Store as string — don't setState with an Error object directly
    setError(err instanceof Error ? err.message : 'An unexpected error occurred');
  } finally {
    setIsLoading(false);
  }
};

3. Widget rates don't match the main app

Widgets run in a separate process and can't read your app's in-memory state. Any data you want to share must go through a persistent store. Step 5 covers this.

Step 5: Adding a Home Screen Widget (Rork Max Required)

Widgets are generated by Rork Max using its SwiftUI native generation. Use this prompt:

Add a home screen widget to the currency converter app.

Specs:
- Size: small (2x2) only
- Display: USD/JPY and EUR/JPY rates
- Refresh: every 60 minutes using TimelineEntry
- Data source: read rates from an AppGroup shared container

Implement with SwiftUI and WidgetKit.

Sharing data between the widget and the main app requires an App Group. After enabling it in Xcode under Signing & Capabilities, add this to the main app's rate-fetching code:

// Save rates for the widget after a successful fetch
const saveRatesForWidget = (rates: Record<string, number>) => {
  const widgetData = {
    usdJpy: rates['JPY'],
    eurJpy: rates['JPY'] / rates['EUR'],  // Cross rate calculation
    updatedAt: new Date().toISOString(),
  };
  // Write to shared container via the NativeModule Rork Max generates
  SharedPreferences.setSharedValue('widgetRates', JSON.stringify(widgetData));
};

Once the widget is working, you can refine its appearance entirely through Rork Max prompts — "make it more compact", "increase the font size", "add a last-updated timestamp" all work well.

Before You Ship

Two quick things to sort out before submitting to the App Store:

Rate caching: The free tier gives you 1,500 requests per month. If your app fetches on every open, that runs out fast with even modest usage. Store the last fetch timestamp in AsyncStorage and only refetch after 30–60 minutes. It's a small addition that keeps you well inside the free limit.

Disclaimer text: Adding a note like "Rates are for reference only and may differ from actual transaction rates" in the app footer is good practice. It's also a minor detail that can prevent an App Store rejection on financial apps.

From here, natural next steps are adding a historical rate chart or a multi-currency comparison view. The ExchangeRate-API paid plan includes historical data endpoints, and Rork's AI generation makes adding charts a matter of a few prompts.

The pattern you've learned here — fetch, handle errors, cache, share data with a widget — applies directly to weather, stocks, news, and just about any other live-data app you'll want to build next.

For more on connecting to external APIs in Rork, see the 外部 API 連携の基本ガイド.

Share

Thank You for Reading

Rork Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $10 for lifetime access
View Membership →

If you found this article helpful, a small tip ($1.50) would mean a lot to us. Your support helps keep this site ad-free and covers server and hosting costs.

Related Articles

Dev Tools2026-03-28
Build a Music Player App with Rork — Audio Playback Implementation Guide Using expo-av
Learn how to build a music player app with Rork and expo-av. This step-by-step guide covers playback controls, seek bars, playlist management, and background audio with practical code examples.
Dev Tools2026-03-28
Rork App Architecture Patterns Guide— Building Maintainable Apps with MVVM, Clean Architecture, and Dependency Injection
A comprehensive guide to architecture patterns for Rork mobile apps. Learn how to implement MVVM, Clean Architecture, and dependency injection in React Native / Expo to build scalable and maintainable applications.
Getting Started2026-04-19
Build a Medication Tracker App with Rork — Never Miss a Dose Again
Learn how to build a medication tracker app with Rork from scratch. This practical guide covers drug registration, daily check-ins, reminder notifications, and history tracking — no coding required.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →