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 buil
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
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
});
});
}
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('');
}
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();
}
What Makes This Different
- Free — No monthly subscription
- No account — Upload CSV, get labels, done
- Client-side — Data never leaves the browser (privacy)
- Works offline — After loading, no internet needed
- 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.
Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.