Build a QR Code Generator in 10 Minutes with APIStack
TutorialTutorialQR CodeJavaScriptBeginner-Friendly

Build a QR Code Generator in 10 Minutes with APIStack

Create a production-ready QR code generator with custom styling, logos, and download options using APIStack's free QR Code API. Perfect for beginners!

APIStack Team
APIStack Team
November 14, 2025
10 min read

QR codes are everywhere - restaurant menus, event tickets, business cards, product packaging. But did you know you can build your own QR code generator in just 10 minutes?

In this tutorial, we'll create a beautiful, production-ready QR code generator with:

Custom content (URLs, text, contact info)
Color customization
Size control
Instant download

No backend needed. No credit card required. 100% free forever with APIStack's QR Code API.

What You'll Build

A web app that lets users:

  • 📝Enter any text, URL, or data
  • 🎨Choose custom colors
  • 📏Select size (100x100 to 1000x1000)
  • 💾Download QR codes instantly

Time to complete: 10-15 minutes
Difficulty: Beginner-friendly
Prerequisites: Basic HTML/CSS/JavaScript knowledge

1

Get Your Free API Access

First, let's get your API key from APIStack:

1.

Go to apistack.pro/signup

Create a free account in 30 seconds

2.

Verify your email

Check your inbox for the verification link

3.

Copy your API key

Found in your dashboard under "API Keys"

✨ Pro tip: No credit card required! APIStack's free tier includes 1,000 API calls per month - perfect for personal projects and small businesses.

2

Test the API (No Code Required)

Before writing code, let's make sure everything works:

1.

Go to the API Playground

Find the QR Code Generator API

2.

Try generating a test QR code

Enter "https://apistack.pro" and click Generate

3.

Scan the QR code with your phone

It should open apistack.pro

3

Set Up Your Project

Create a new folder and add three files:

mkdir qr-generator
cd qr-generator
touch index.html style.css script.js

That's it! No npm install, no build tools, no complicated setup.

4

Build the HTML

Open index.html and add:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>QR Code Generator - APIStack</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>🔲 QR Code Generator</h1>
            <p>Create custom QR codes instantly</p>
        </div>

        <div class="generator-card">
            <!-- Input Section -->
            <div class="input-section">
                <label for="qr-text">Enter URL or Text</label>
                <textarea 
                    id="qr-text" 
                    placeholder="https://example.com"
                    rows="3"
                ></textarea>

                <!-- Options Grid -->
                <div class="options-grid">
                    <div class="option">
                        <label for="qr-size">Size (px)</label>
                        <input 
                            type="number" 
                            id="qr-size" 
                            value="300" 
                            min="100" 
                            max="1000"
                        >
                    </div>

                    <div class="option">
                        <label for="qr-color">Color</label>
                        <input 
                            type="color" 
                            id="qr-color" 
                            value="#000000"
                        >
                    </div>

                    <div class="option">
                        <label for="qr-bg">Background</label>
                        <input 
                            type="color" 
                            id="qr-bg" 
                            value="#ffffff"
                        >
                    </div>
                </div>

                <button id="generate-btn" class="btn-primary">
                    Generate QR Code
                </button>
            </div>

            <!-- Preview Section -->
            <div class="preview-section">
                <div id="qr-preview">
                    <p class="placeholder-text">
                        Your QR code will appear here
                    </p>
                </div>

                <button id="download-btn" class="btn-secondary" style="display: none;">
                    Download QR Code
                </button>
            </div>
        </div>

        <!-- Stats Footer -->
        <div class="stats-footer">
            <div class="stat">
                <span class="stat-value">FREE</span>
                <span class="stat-label">No cost</span>
            </div>
            <div class="stat">
                <span class="stat-value">1000</span>
                <span class="stat-label">Calls/month</span>
            </div>
            <div class="stat">
                <span class="stat-value">∞</span>
                <span class="stat-label">QR codes</span>
            </div>
        </div>
    </div>

    <script src="script.js"></script>
</body>
</html>

What's happening here: We've created a simple form with a text area for the content, inputs for customization (size, colors), and a preview area for the generated QR code.

5

Add Beautiful Styling

Open style.css:

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    min-height: 100vh;
    padding: 40px 20px;
}

.container {
    max-width: 900px;
    margin: 0 auto;
}

.header {
    text-align: center;
    color: white;
    margin-bottom: 40px;
}

.header h1 {
    font-size: 2.5rem;
    margin-bottom: 10px;
}

.header p {
    font-size: 1.2rem;
    opacity: 0.9;
}

.generator-card {
    background: white;
    border-radius: 20px;
    padding: 40px;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 40px;
}

.input-section label {
    display: block;
    font-weight: 600;
    margin-bottom: 8px;
    color: #333;
}

#qr-text {
    width: 100%;
    padding: 12px;
    border: 2px solid #e0e0e0;
    border-radius: 8px;
    font-size: 1rem;
    font-family: inherit;
    resize: vertical;
    transition: border-color 0.3s;
}

#qr-text:focus {
    outline: none;
    border-color: #667eea;
}

.options-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 16px;
    margin: 20px 0;
}

.option label {
    font-size: 0.875rem;
}

.option input[type="number"],
.option input[type="color"] {
    width: 100%;
    padding: 8px;
    border: 2px solid #e0e0e0;
    border-radius: 8px;
    font-size: 1rem;
}

.option input[type="color"] {
    height: 45px;
    cursor: pointer;
}

.btn-primary, .btn-secondary {
    width: 100%;
    padding: 14px;
    border: none;
    border-radius: 8px;
    font-size: 1rem;
    font-weight: 600;
    cursor: pointer;
    transition: transform 0.2s, box-shadow 0.2s;
}

.btn-primary {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    color: white;
}

.btn-primary:hover {
    transform: translateY(-2px);
    box-shadow: 0 6px 20px rgba(102, 126, 234, 0.4);
}

.btn-secondary {
    background: #10b981;
    color: white;
    margin-top: 16px;
}

.btn-secondary:hover {
    transform: translateY(-2px);
    box-shadow: 0 6px 20px rgba(16, 185, 129, 0.4);
}

.preview-section {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
}

#qr-preview {
    width: 100%;
    min-height: 300px;
    background: #f9fafb;
    border: 2px dashed #d1d5db;
    border-radius: 12px;
    display: flex;
    align-items: center;
    justify-content: center;
}

#qr-preview img {
    max-width: 100%;
    border-radius: 8px;
}

.placeholder-text {
    color: #9ca3af;
    text-align: center;
    font-size: 1rem;
}

.stats-footer {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 20px;
    margin-top: 30px;
}

.stat {
    background: rgba(255, 255, 255, 0.2);
    backdrop-filter: blur(10px);
    padding: 20px;
    border-radius: 12px;
    text-align: center;
    color: white;
}

.stat-value {
    display: block;
    font-size: 2rem;
    font-weight: bold;
    margin-bottom: 5px;
}

.stat-label {
    font-size: 0.875rem;
    opacity: 0.9;
}

@media (max-width: 768px) {
    .generator-card {
        grid-template-columns: 1fr;
    }
    
    .header h1 {
        font-size: 2rem;
    }
    
    .stats-footer {
        grid-template-columns: 1fr;
    }
}

Design notes: This uses a modern gradient background, glassmorphism effects, and smooth animations. The layout is fully responsive and works perfectly on mobile devices.

6

Add the API Integration

Now the magic part! Open script.js:

// Replace with your APIStack key
const API_KEY = 'your_apistack_key_here';
const QR_API_URL = 'https://apistack.pro/api/qr/generate';

// DOM elements
const generateBtn = document.getElementById('generate-btn');
const downloadBtn = document.getElementById('download-btn');
const qrText = document.getElementById('qr-text');
const qrSize = document.getElementById('qr-size');
const qrColor = document.getElementById('qr-color');
const qrBg = document.getElementById('qr-bg');
const qrPreview = document.getElementById('qr-preview');

let currentQrUrl = '';

// Generate QR code
async function generateQR() {
    const text = qrText.value.trim();
    
    if (!text) {
        alert('Please enter some text or URL');
        return;
    }

    // Show loading state
    generateBtn.textContent = 'Generating...';
    generateBtn.disabled = true;

    try {
        // Build API URL with parameters
        const params = new URLSearchParams({
            data: text,
            size: qrSize.value,
            color: qrColor.value.replace('#', ''),
            bgcolor: qrBg.value.replace('#', '')
        });

        const response = await fetch(`${QR_API_URL}?${params}`, {
            headers: {
                'Authorization': `Bearer ${API_KEY}`
            }
        });

        if (!response.ok) {
            throw new Error('Failed to generate QR code');
        }

        // Get image URL
        const blob = await response.blob();
        currentQrUrl = URL.createObjectURL(blob);

        // Display QR code
        qrPreview.innerHTML = `<img src="${currentQrUrl}" alt="QR Code" />`;
        
        // Show download button
        downloadBtn.style.display = 'block';

    } catch (error) {
        console.error('Error:', error);
        alert('Failed to generate QR code. Please try again.');
    } finally {
        generateBtn.textContent = 'Generate QR Code';
        generateBtn.disabled = false;
    }
}

// Download QR code
function downloadQR() {
    if (!currentQrUrl) return;

    const link = document.createElement('a');
    link.href = currentQrUrl;
    link.download = `qr-code-${Date.now()}.png`;
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
}

// Event listeners
generateBtn.addEventListener('click', generateQR);
downloadBtn.addEventListener('click', downloadQR);

// Generate on Enter key (in textarea)
qrText.addEventListener('keydown', (e) => {
    if (e.key === 'Enter' && e.ctrlKey) {
        generateQR();
    }
});

⚠️ Important: Replace 'your_apistack_key_here' with your actual API key from step 1!

Code breakdown: We're using the Fetch API to call APIStack's QR endpoint with custom parameters. The response is a PNG image that we display and allow users to download.

7

Test Your App

Open index.html in your browser and try:

✅ Generate a basic QR code

Enter "https://google.com" and click Generate

🎨 Try different colors

Change the color to blue (#0000FF)

📏 Adjust the size

Try 500px for a larger QR code

💾 Download it

Click the download button

📱 Scan with your phone

Use your camera app to verify it works

What's Next?

🚀 Deploy It

  • • Deploy to Vercel (free hosting)
  • • Or use Netlify Drop
  • • Share with friends!

✨ Add Features

  • • Logo in center of QR code
  • • Batch generation
  • • QR code templates
  • • Analytics tracking

🎯 Real Use Cases

  • • Restaurant menus
  • • Business cards
  • • Event tickets
  • • Product packaging

🔗 Explore More APIs

  • • URL Shortener API
  • • Email Validator API
  • • Weather API
  • • 100+ more APIs free

Common Issues & Solutions

❌ "Failed to generate QR code" error

Solution:

  • Check that your API key is correct
  • Make sure you have internet connection
  • Verify you haven't exceeded 1,000 calls/month
🎨 Colors not working

Solution:

The API expects hex codes without the # symbol. Our code removes it automatically with .replace('#', '')

📱 QR code won't scan

Solution:

  • Increase the size to at least 300px
  • Use high contrast colors (black on white works best)
  • Ensure the URL is valid (starts with http:// or https://)

🎉 Congratulations!

You just built a fully functional QR code generator in 10 minutes! This same app could be used for:

🍕Restaurant contactless menus
🎫Event ticketing systems
💼Digital business cards
📦Product authentication

Ready to Build More?

APIStack has 104 APIs - all free to start. Build weather apps, currency converters, image processors, and more.

Found this tutorial helpful? Share it with your friends!