Import Customer CSV Data Into Postgres Without Making Postgres Parse Their Spreadsheet

Postgres is very good at storing structured data.

Your customer's spreadsheet is not structured according to your database.

That gap is where an application-level importer belongs.

Do not make the database your spreadsheet UX

Suppose your contacts table expects first_name, last_name, email, company.

Your customer uploads Given Name, Surname, Email Address, Employer.

Before Postgres should see anything, somebody needs to parse the file, identify columns, map uploaded columns to application fields, validate required values, normalize types, and show the customer what is wrong.

That somebody can be your own import subsystem.

Or it can be Bootstrapware Importer.

Keep the responsibilities clean

The browser handles spreadsheet-specific UX:

CSV / XLSX / TSV → Bootstrapware Importer → normalized JavaScript objects

Your backend then handles application-specific work:

normalized rows → authenticate → enforce business rules → transaction / inserts → Postgres

Bootstrapware does not connect to your Postgres database and does not receive the row data.

Example shape

<Importer
  importerId="imp_contacts"
  publishableKey="bsw_live_pub_..."
  onComplete={async (rows) => {
    await fetch("/api/contacts/import", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ rows }),
    });
  }}
/>

Your /api/contacts/import endpoint validates the authenticated user and performs the database work, for example with parameterized SQL:

for (const row of rows) {
  await client.query(
    `insert into contacts (email, name) values ($1, $2)
     on conflict (email) do update set name = excluded.name`,
    [row.email, row.name],
  );
}

Why not just use Postgres COPY?

If you control the CSV and its schema, direct bulk loading can be excellent.

Customer uploads are different.

The spreadsheet may have unexpected headers, missing fields, invalid values, and data the customer needs to review before insertion.

Bootstrapware is not trying to replace Postgres bulk-loading tools.

It is solving the customer-facing workflow before the database operation.

Related: Importer · onComplete · Validate before insert · Neon · Prisma