DEV Community

seller-mind
seller-mind

Posted on

How I Built a Batch Shipping Label Generator for Small E-Commerce Sellers

If you ship more than 5 orders a day, you know the pain: manually creating labels one by one. Each label needs the same info — return address, weight class, service type — just with different recipient addresses.

I built a tool that takes a CSV of addresses and generates all your labels at once.

The Problem

Small e-commerce sellers often use:

  • Manual entry: Copy-paste addresses into carrier websites one by one
  • Spreadsheets: Track orders but can't generate labels
  • Expensive software: $50+/month tools that are overkill for < 50 orders/day

There's a gap between "completely manual" and "enterprise TMS." I wanted to fill it.

CSV Format

The tool accepts a simple CSV:

name,address_line_1,address_line_2,city,state,zip,country,weight_oz
John Doe,123 Main St,,Portland,OR,97201,US,8
Jane Smith,456 Oak Ave,Apt 2B,Seattle,WA,98101,US,12
Enter fullscreen mode Exit fullscreen mode

Minimal required fields:

  • name — recipient name
  • address_line_1 — street address
  • city, state, zip — location
  • weight_oz — package weight in ounces

Implementation

1. CSV Parsing

I use PapaParse for robust CSV handling (handles quoted fields, commas in addresses, etc.):

import Papa from 'papaparse';

function parseCSV(file) {
  return new Promise((resolve, reject) => {
    Papa.parse(file, {
      header: true,
      skipEmptyLines: true,
      complete: (results) => {
        const labels = results.data.map((row, index) => ({
          id: index + 1,
          recipient: row.name,
          address: formatAddress(row),
          weight: row.weight_oz,
          service: 'USPS First Class'
        }));
        resolve(labels);
      },
      error: reject
    });
  });
}
Enter fullscreen mode Exit fullscreen mode

2. Label Generation

Each label is rendered as a print-ready format:

function generateLabelHTML(labels) {
  return labels.map(label => `
    <div class="label" style="page-break-after: always;">
      <div class="from">
        <strong>Return:</strong><br>
        ${RETURN_ADDRESS.name}<br>
        ${RETURN_ADDRESS.line1}<br>
        ${RETURN_ADDRESS.city}, ${RETURN_ADDRESS.state} ${RETURN_ADDRESS.zip}
      </div>
      <div class="to">
        <strong>Ship to:</strong><br>
        ${label.recipient}<br>
        ${label.address}<br>
        Weight: ${label.weight} oz
      </div>
      <div class="barcode">
        <!-- USPS tracking barcode placeholder -->
      </div>
    </div>
  `).join('');
}
Enter fullscreen mode Exit fullscreen mode

3. Print-to-PDF

The tool generates HTML formatted for standard 4×6 shipping labels. Users print directly from the browser:

function printLabels(html) {
  const printWindow = window.open('', '_blank');
  printWindow.document.write(`
    <html>
      <head>
        <title>Shipping Labels</title>
        <style>
          @page { size: 4in 6in; margin: 0.125in; }
          .label { font-family: 'Courier New', monospace; font-size: 10pt; }
          /* ... more styles ... */
        </style>
      </head>
      <body>${html}</body>
    </html>
  `);
  printWindow.document.close();
  printWindow.print();
}
Enter fullscreen mode Exit fullscreen mode

What Makes This Different

  1. Free — No monthly subscription
  2. No account — Upload CSV, get labels, done
  3. Client-side — Data never leaves the browser (privacy)
  4. Works offline — After loading, no internet needed
  5. Customizable return address — Save your return address in localStorage

Future Plans

  • Integration with USPS API for real tracking numbers
  • Support for UPS/FedEx label formats
  • CSV templates for different carriers
  • Batch address validation

FTC Disclosure: I built this tool. Free to use, no affiliate links.

How do you handle batch label generation? What tools do you use? Let me know in the comments.

Top comments (0)