The last CSV importer
you'll ever ship.
Drop in, done.
Rowslint is a drop-in widget for CSV and Excel imports. Your users map columns, clean data, and sync millions of rows — without you writing a parser, a validator, or a support ticket.
Three steps.
Zero support tickets.
Every import pipeline starts the same way and fails in the same places. Rowslint ships the last 10% — the messy, user-facing part — so you can focus on what happens after the data lands.
Embed in 2 lines
One React, Vue, or vanilla JS snippet. It inherits your theme tokens, your auth session, and your brand.
Define your schema
Declare target fields with types, regexes, enums, or async validators. Rowslint handles the rest.
Users import, you receive clean data
Rows stream to your webhook or database — typed, deduplicated, and validated. Nothing sits on our servers.
Built by people
who've been on-call.
Every feature in Rowslint exists because someone, somewhere, got paged at 3am for a malformed CSV. We've seen the worst data you can imagine — and shipped defenses against it.
Two lines,
no backend required.
Point Rowslint at a schema. Give it a handler. Ship. React, Vue, Svelte, vanilla JS — pick your poison. Full TypeScript types out of the box.
Schema types flow all the way to your onImport handler. No any. No casts.
@rowslint/importer-js, /react, /vue, /svelte — same API, same bundle size.
Lightweight by design. Validators, Excel parser, and locale bundles load on demand.
Bring your own UI. Use hooks for file parsing, mapping, and validation only.
Your users'
spreadsheet mess,
mapped in milliseconds.
Rowslint fingerprints headers and sample data against your schema. Fuzzy matching, synonyms, case, whitespace, and common typos are handled before the user sees the screen. They rarely need to lift a finger.
Bad data
stops at the door.
Define rules once — Zod, Yup, regex, or async fetches to your API. Rowslint runs them on every row and surfaces errors inline. Users fix, skip, or bulk-edit before anything leaves the browser.
| Field | Rule | Sample | Status |
|---|---|---|---|
| z.string().email() | "[email protected]" | passing | |
| phone | z.string().regex(/^\+?[1-9]\d{7,14}$/) | "+14155550142" | passing |
| plan | z.enum(["free","pro","enterprise"]) | "pro" | passing |
| mrr | z.number().positive() | -32.00 | blocked |
| domain | async (v) => await checkDNS(v) | "acm.io" | review |
| created_at | z.coerce.date() | "2026-13-01" | blocked |
Private by default.
Compliant by design.
Rowslint was built for regulated industries. The default architecture is privacy-first: parsing, validation, and column mapping happen in the user's browser. Nothing persists on our infrastructure unless you explicitly ask it to.
Files are parsed in-browser and discarded the moment your handler returns.
EU data residency. Privacy-first by default.
Rows never touch our servers by default.
Customer-managed encryption keys for sensitive workloads.
Priced per row.
Never per seat.
All plans include a 14-day free trial. No credit card required. Need a custom plan? Contact us for enterprise solutions.
- ✓ 100 file imports / month
- ✓ Basic data validation
- ✓ CSV & Excel formats
- ✓ Email notifications
- ✓ Standard support
- ✓ 10,000 file imports / month
- ✓ Advanced data validation
- ✓ CSV, Excel & JSON formats
- ✓ Custom field mapping
- ✓ Webhook integrations
- ✓ Advanced analytics
- ✓ Priority support
- ✓ 50,000 file imports / month
- ✓ Enterprise-grade validation
- ✓ All file formats supported
- ✓ Custom branding
- ✓ API access
- ✓ Custom data transformations
- ✓ Dedicated support
Faster to ship.
Cheaper to run.
Nicer to use.
We've built these systems before — in-house, with competitors, from scratch. Rowslint is what we wish we'd had.
Answers,
before you ask.
Couldn't find what you're looking for? Check the documentation →