← Back to Blog

How to Add CSV Import to Your React App in 5 Minutes

by ImportKit Team

If you're building a SaaS application, your users will eventually need to import data from spreadsheets. Customer lists, product catalogs, employee records, pricing tables — the data lives in CSV and Excel files, and your app needs to ingest it cleanly.

Building this from scratch takes 2-4 weeks. Parsing edge cases, mapping columns, validating data, handling errors — it's a rabbit hole. This tutorial shows you how to skip all of that and have a working CSV import in your React app in under 5 minutes.

What You'll Build

By the end of this tutorial, your app will have:

  • A drag-and-drop file upload that accepts CSV and Excel files
  • AI-powered column mapping that automatically matches user columns to your schema
  • Built-in validation for emails, numbers, dates, enums, and custom rules
  • Inline error correction so users can fix problems without re-uploading
  • A clean, mobile-responsive UI that matches your brand
  • Step 1: Install the Package

    npm install @importkit/react

    The package is lightweight — only three dependencies (papaparse, read-excel-file, fflate) and works with React 18 and 19.

    Step 2: Get Your API Key

    Sign up at dashboard.importkit.app and copy your API key from the welcome screen. It looks like ik_live_.... The free tier gives you 5,000 rows per month — enough to build and test.

    Step 3: Add the Widget

    Here's a complete working example for importing a contact list:

    import { ImportWidget } from '@importkit/react';

    function ContactImport() { return ( <ImportWidget apiKey="ik_live_your_key_here" fields={[ { name: 'email', label: 'Email', type: 'email', required: true }, { name: 'name', label: 'Full Name', required: true }, { name: 'company', label: 'Company' }, { name: 'phone', label: 'Phone', type: 'phone' }, ]} onComplete={(data) => { console.log('Imported rows:', data); // Send to your API fetch('/api/contacts/import', { method: 'POST', body: JSON.stringify({ rows: data }), }); }} onError={(error) => console.error('Import failed:', error)} /> ); }

    That's it. Your users can now drag a CSV file onto the widget, confirm the AI-suggested field mapping, fix any validation errors inline, and import clean data into your app.

    Step 4: Define Your Fields

    The fields prop tells ImportKit what data you expect. Each field has a name, label, and optional type and validation rules.

    Supported Field Types

  • text — Default. Any string value.
  • email — Validates email format automatically.
  • number — Validates numeric values. Supports min/max ranges.
  • date — Auto-detects date formats (MM/DD/YYYY, DD-MM-YYYY, ISO 8601, and more).
  • phone — Normalizes phone number formats.
  • enum — Restricts values to a defined list with AI-powered synonym matching.
  • Example: Product Catalog Import with Validation

    const fields = [
      { name: 'sku', label: 'SKU', required: true },
      { name: 'product_name', label: 'Product Name', required: true },
      {
        name: 'price',
        label: 'Price',
        type: 'number',
        required: true,
        validate: [
          { type: 'min', value: 0, message: 'Price must be positive' },
        ],
      },
      {
        name: 'category',
        label: 'Category',
        type: 'enum',
        enum: {
          values: ['Electronics', 'Clothing', 'Food', 'Home', 'Sports'],
          hints: ['Tech, Gadgets', 'Apparel, Fashion', 'Grocery', 'Furniture, Decor', 'Fitness, Outdoor'],
        },
      },
      {
        name: 'stock',
        label: 'Stock Count',
        type: 'number',
        validate: [
          { type: 'min', value: 0 },
        ],
      },
    ];

    The hints property in enum fields tells the AI what synonyms to accept. If a user's CSV has "Tech" in the category column, ImportKit will automatically map it to "Electronics".

    Step 5: Customize the Look

    Match the widget to your app's design with the theme prop:

    <ImportWidget
      apiKey="ik_live_..."
      fields={fields}
      theme={{
        primaryColor: '#6366f1',
        borderRadius: '12px',
        fontFamily: 'Inter, sans-serif',
      }}
      onComplete={handleImport}
    />

    Available theme properties: primaryColor, successColor, errorColor, borderColor, borderRadius, fontFamily, and fontSize.

    How the AI Field Mapping Works

    When a user uploads a CSV, ImportKit runs a 6-step matching cascade to map their columns to your fields:

  • Exact match — "Email" maps to your "email" field
  • Case-insensitive match — "EMAIL" maps to "email"
  • Learned mappings — Uses history from previous imports
  • Hint-based matching — Checks the hints you provided in enum definitions
  • AI semantic matching — "Electronic Mail Address" maps to "email"
  • Fuzzy fallback — Handles typos and abbreviations
  • Users see the suggested mapping and can adjust it before confirming. In practice, the AI gets it right 90%+ of the time, so most users just click confirm and import.

    Handling the Imported Data

    The onComplete callback receives an array of clean, validated objects:

    onComplete={(data) => {
      // data is an array of objects like:
      // [
      //   { email: 'alice@acme.com', name: 'Alice Johnson', company: 'Acme Inc', phone: '+1-555-0101' },
      //   { email: 'bob@corp.io', name: 'Bob Smith', company: 'TechCorp', phone: '+1-555-0102' },
      //   ...
      // ]

    // Send to your backend await fetch('/api/import', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ rows: data }), }); }}

    All data processing happens client-side in the user's browser. No CSV data is sent to ImportKit's servers — only the field mapping metadata passes through the API for AI-powered suggestions.

    Next.js Integration

    ImportKit works seamlessly with Next.js App Router. Since the widget uses browser APIs, add the 'use client' directive:

    'use client';

    import { ImportWidget } from '@importkit/react';

    export default function ImportPage() { return ( <div className="max-w-2xl mx-auto p-8"> <h1 className="text-2xl font-bold mb-6">Import Your Data</h1> <ImportWidget apiKey={process.env.NEXT_PUBLIC_IMPORTKIT_API_KEY!} fields={[ { name: 'email', label: 'Email', type: 'email', required: true }, { name: 'name', label: 'Name', required: true }, ]} onComplete={async (data) => { const response = await fetch('/api/import', { method: 'POST', body: JSON.stringify(data), }); if (response.ok) { window.location.href = '/dashboard'; } }} /> </div> ); }

    Comparing Alternatives

    If you're evaluating options for adding CSV import to your React app, here's how the approaches compare:

    Build from Scratch (2-4 Weeks)

    You'll need to handle CSV parsing (papaparse), Excel reading (SheetJS), field mapping UI, validation logic, error display, and edge cases like encoding detection and date format parsing. Then maintain it forever. Suitable if CSV import is your core product, not if it's a supporting feature.

    Flatfile / OneSchema ($500-2,000/month)

    Enterprise-grade data onboarding platforms. Excellent products but priced for large teams. If your SaaS is charging $200+/seat/month and handles high-volume imports, these are worth evaluating. Overkill for early-stage products.

    ImportKit ($0-149/month)

    Production-ready widget that covers 90% of CSV import needs. Free tier for building and testing, Starter at $49/month for production use. MIT-licensed widget source code. Best fit for SaaS products that need solid CSV import without enterprise budgets or weeks of development time.

    Get Started

    Install the package, grab an API key, and paste the component into your app. The free tier includes 5,000 rows per month with no credit card required.

    npm install @importkit/react
    Sign up for free at dashboard.importkit.app and try the live demo on our homepage to see the widget in action before you integrate.

    Ready to add CSV imports to your SaaS?

    ImportKit gives you production-ready CSV imports in 5 minutes.

    Start Free Trial