← Back to list

My Second VibeCode Arena Challenge: Building a Quote Generator That Actually Works

Introduction: Lightning Strikes Twice

Aryanpatil · 2026-04-01 12:53 · 0 claps · 7.8 min read
#react #api #coding-challenge #hackerearth
Open on Medium ↗
Wiki topics: 💻 · Programming 🌐 · Web Development

My Second VibeCode Arena Challenge: Building a Quote Generator That Actually Works

Introduction: Lightning Strikes Twice

After the success of my first VibeCode Arena challenge (the Todo List App), I was hungry to create another one.

This time, I wanted to focus on something different. The todo list teaches state management. But what about API integration? What about handling real external data? What about the unique challenges that come with network requests?

So I created my second challenge: A Random Quote Generator.

Here’s the twist: I used a different AI model this time. Instead of Mistral-Nemo, I asked Codestral-2508 to generate the solution.

This taught me something interesting: Different AI models approach the same problem very differently. And that diversity is exactly what makes for great learning.

Let me share what I built, what I learned, and why this challenge will push your React skills forward.

Why a Quote Generator? (It’s Deeper Than It Sounds)

When I was brainstorming my second challenge, I wanted something that would teach fundamentally different concepts than the todo list.

The todo list taught: — State management — Database operations — CRUD patterns

A quote generator needed to teach: — API integration — Async/await patterns — Error handling — Loading states — Preventing duplicate data — User feedback mechanisms

And here’s the thing: Most developers struggle with API integration.

They know how to write React. They know how to manage state. But handling an external API? Dealing with network latency? Preventing race conditions? Managing errors when the API goes down?

That’s where things get messy.

A quote generator is simple enough to understand in 5 minutes but complex enough to have 10+ optimization points. It’s the perfect learning vehicle.

The Challenge: Random Quote Generator

Here’s what I asked the AI to build:

Build a Random Quote Generator app that:

  • Displays a random motivational or famous quote
  • Shows the quote author/source
  • Has a “Get New Quote” button to fetch another quote
  • Has a “Copy Quote” button to copy the quote text to clipboard
  • Shows a loading state while fetching quotes
  • Prevents showing the same quote twice in a row
  • Has a clean, attractive UI
  • Handles errors gracefully
  • Code should be clean and maintainable

Simple requirements. But notice how many things need to work together.

What Codestral-2508 Generated

Here’s the code that Codestral-2508 created:

import React, { useState, useEffect } from ‘react’; import ‘./QuoteGenerator.css’;

const QuoteGenerator = () => { const [quote, setQuote] = useState(‘’); const [author, setAuthor] = useState(‘’); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [lastQuote, setLastQuote] = useState(‘’);

// Fetch a new quote from the API const fetchQuote = async () => { setLoading(true); setError(null);

try { const response = await fetch(‘https://api.quotable.io/random'); if (!response.ok) { throw new Error(‘Failed to fetch quote’); }

const data = await response.json();

// Prevent showing the same quote twice in a row if (data.content === lastQuote) { return fetchQuote(); // Try again if same quote }

setQuote(data.content); setAuthor(data.author); setLastQuote(data.content); } catch (err) { setError(err.message); } finally { setLoading(false); } };

// Initial load useEffect(() => { fetchQuote(); }, []);

// Copy quote to clipboard const copyToClipboard = () => { if (!quote) return;

navigator.clipboard.writeText(${quote} — ${author}) .then(() => alert(‘Quote copied to clipboard!’)) .catch(() => alert(‘Failed to copy quote’)); };

return ( <div className=”quote-container”> <h1>Random Quote Generator</h1>

{loading ? ( <div className=”loading”>Loading quote…</div> ) : error ? ( <div className=”error”>{error}</div> ) : ( <div className=”quote-content”> <p className=”quote-text”>”{quote}”</p> <p className=”quote-author”>- {author}</p> </div> )}

<div className=”button-group”> <button onClick={fetchQuote} disabled={loading} className=”new-quote-btn” > {loading ? ‘Loading…’ : ‘Get New Quote’} </button> <button onClick={copyToClipboard} disabled={loading || !quote} className=”copy-btn” > Copy Quote </button> </div> </div> ); };

export default QuoteGenerator;

First impression: This is solid code. It handles most of the requirements. It works.

But take a closer look. There are at least 8 clear improvements waiting to be made.

What Makes This Code Good (And Why There’s Room for Better)

The Good Parts ✅

1. Clean structure — Components, functions, and state are organized logically

2. Error handling — Catches failures and shows them to users

3. Loading state — Users see feedback while waiting

4. Duplicate prevention — The app prevents showing the same quote twice (smart!)

5. Clipboard integration — Uses modern Clipboard API

6. Button feedback — Buttons disable during loading

The Improvement Opportunities ��

1. Recursive API calls — The duplicate prevention uses recursion (what if it keeps fetching the same quote?)

2. Alert for feedback — Using alert() feels outdated. Better UX alternatives exist

3. CSS dependency — Relies on external CSS file (what about styling?)

4. Network resilience — What if the API is slow? What about retries?

5. Accessibility — Are ARIA labels needed? Is the UI keyboard accessible?

6. State optimization — Can we reduce the number of state variables?

7. UX polish — Smooth transitions? Better loading indicators?

8. Data validation — What if the API returns unexpected data?

This is where the real learning happens. You take working code and make it great.

Why This Challenge Matters

Every React developer will eventually integrate an API. It’s not optional. It’s fundamental.

But most tutorials gloss over the hard parts: — What happens when the network is slow? — What if the API fails? — How do you provide good user feedback? — How do you prevent race conditions? — How do you handle edge cases?

This challenge forces you to think about all of these.

When you improve Codestral-2508’s code, you’re not just making it “work better” — you’re learning to build resilient, user-friendly applications.

What You’ll Learn

1. Async/Await Deep Dive

The code uses async/await to fetch quotes. But there are patterns you can learn: — Managing async state properly — Handling race conditions — Cancelling requests when needed — Retrying failed requests

2. Error Handling Strategies

Different errors need different handling: — Network errors (API is down) — Parsing errors (API returns unexpected data) — Timeout errors (API is slow) — User errors (they click too fast)

You’ll learn to handle all of these gracefully.

3. User Feedback Patterns

Alerts are bad UX. Better approaches: — Toast notifications — Inline error messages — Loading skeletons — Graceful degradation

4. Preventing Unwanted Behavior

The duplicate prevention works, but there are better approaches: — Keep a history of shown quotes — Use a set to track shown quotes — Implement a “don’t repeat for N quotes” rule

5. Accessibility & Keyboard Navigation

Does this work with a screen reader? Can you use it with just a keyboard? These questions matter.

6. API Integration Best Practices

Learn to: — Cache results — Debounce requests — Implement timeouts — Handle rate limiting — Validate API responses

The Challenge Link

**Click here to access the challenge**

Or visit: https://vibecodearena.ai/share/2f57fdc9-d2e4-4aab-bae4-08a0516fb1fb

When you click it, you’ll see: — The challenge requirements — Codestral-2508’s generated code — A blank editor to write your improvement — Real-time metrics of code quality

How to Approach This Challenge

If You’re a Beginner:

1. Read the code carefully — What does each function do? Why does it exist?

2. Understand the flow — User clicks button → API call → Quote displayed

3. Spot one issue — Don’t try to fix everything. Find one thing:

– Replace alert() with a better notification?

– Add validation to the API response?

– Improve the loading indicator?

4. Make that one improvement — Submit and see the metrics improve

If You’re Intermediate:

1. Analyze the entire flow — Is there duplicated state? Are there unnecessary re-renders?

2. Improve error handling — Different errors should be handled differently

3. Enhance UX — Replace alerts with toast notifications or inline messages

4. Optimize the duplicate prevention — Use a better approach than recursion

5. Add accessibility — Proper ARIA labels, keyboard navigation

If You’re Advanced:

1. Implement caching — Cache quotes to reduce API calls

2. Add retry logic — Automatically retry failed requests with exponential backoff

3. Prevent race conditions — Cancel pending requests when user clicks rapidly

4. Implement timeouts — Don’t wait forever for API responses

5. Add tracking — Track which quotes have been shown, implement smart rotation

6. Create custom hooks — Extract API logic into a useFetch hook

7. Optimize for mobile — Test on slow networks, small screens

What I Learned Creating This Challenge

1. Different AI Models, Different Approaches

Codestral-2508 and Mistral-Nemo solved similar problems differently: — Mistral-Nemo (Todo List): Focused on state management and database integration — Codestral-2508 (Quote Generator): Focused on clean API integration

This taught me that AI models have different strengths. One isn’t “better” — they’re just different.

2. Simple Apps Teach Complex Concepts

A quote generator is 80 lines of code. But improving it teaches: — API integration — Error handling — User feedback — Async patterns — State management

Small projects have big learning potential.

3. The Importance of Constraints

I constrained the requirements: — “Prevent showing the same quote twice” — “Handle errors gracefully” — “Show loading state”

These constraints force developers to think about real-world problems. Without them, the challenge is just “fetch and display data.”

Why You Should Take This Challenge

You’re a developer. You know APIs matter. So here’s why this specific challenge is worth your time:

It’s realistic — You’ll write code like this in real projects ✓ It’s learnable — Not a 6-hour problem, but has depth ✓ It teaches patterns — Async, error handling, state management ✓ It’s different from the first challenge — New concepts to master ✓ You compete against Codestral-2508 — Can you improve on a quality model? ✓ You learn from others — See how different developers optimize it

The Bigger Picture: Building Better APIs

Here’s what most developers miss:

Writing code that uses an API is easy. Writing code that handles an API failing is hard.

The difference between a junior developer and a senior developer is often this: Juniors write code that works. Seniors write code that works when things break.

This challenge teaches you to be a senior.

When you improve Codestral-2508’s code, you’re not just making it faster — you’re making it more resilient, more accessible, more user-friendly.

These skills separate developers who build prototypes from developers who build production systems.

Your Journey

You started last week with no challenges created. Now you have two.

You’ve learned: — How to think like an educator — What makes a good learning challenge — How different AI models approach problems — How to create progression (from state management to API integration)

You’re not just creating challenges — you’re building a learning curriculum.

Final Thoughts: The Challenge is the Teacher

I used to think the challenge was separate from the learning. Like, “I’ll create a challenge, and then people will learn from it.”

I was wrong.

The act of creating the challenge IS the learning.

When I designed the quote generator, I had to think deeply about: — What mistakes developers make with APIs — What patterns matter for resilience — What UX problems exist in the naive implementation — How to structure a challenge that teaches without being overwhelming

Creating challenges made me a better developer.

Now it’s your turn. Try this challenge. Improve on Codestral-2508. Climb the leaderboard.

And then ask yourself: What would I create next?

Challenge Details at a Glance

Challenge Name: Random Quote Generator Difficulty: Beginner-Intermediate Time to Complete: 30–45 minutes AI Model: Codestral-2508 Primary Skills: API Integration, Async/Await, Error Handling, State Management Real-world Application: Weather apps, News feeds, Data dashboards, Any API integration Link: https://vibecodearena.ai/share/2f57fdc9-d2e4-4aab-bae4-08a0516fb1fb

Join the Challenge

Ready to test your API integration skills?

Don’t just read about it — try it. See where you rank. Learn from solutions better than yours. Improve your approach.

**Start the Challenge →**

Share Your Results

After you complete the challenge, I’d love to hear: — What improvements did you make to the quote generator? — What surprised you about the code? — What was the hardest optimization? — How would you build it from scratch differently?

Drop your thoughts in the comments. Let’s learn together.

Have two VibeCode Arena challenges under your belt? Ready to create your third? The momentum is building!

VibeCodeArena #React #API #CodingChallenge #WebDevelopment #Learning #HackerEarth #AsyncAwait #JavaScript #DeveloperJourney


메타데이터
post_id
ab29e7806306
slug
my-second-vibecode-arena-challenge-building-a-quote-generator-that-actually-works-ab29e7806306
url
https://medium.com/@aryanpatil2703/my-second-vibecode-arena-challenge-building-a-quote-generator-that-actually-works-ab29e7806306
canonical_url
https://medium.com/@aryanpatil2703/my-second-vibecode-arena-challenge-building-a-quote-generator-that-actually-works-ab29e7806306
author_url
https://medium.com/@aryanpatil2703
status
ok
fetched_at
2026-07-07 01:49:13