A lightweight Go-based CLI tool that transforms CSV and JSON files using a YAML-driven mapping configuration. Useful for:
- CSV cleanup
- System migrations
- API payload transformation
- Quick data reshaping tasks
Remap takes an input file (CSV or JSON), applies field-level transformations defined in a YAML config, and outputs a transformed file (CSV or JSON).
It is designed as a simple ETL-style pipeline: Input File → Reader → Validation → Mapper → Writer → Output File
Working in enterprise PropTech, I spent a lot of time writing one-off scripts to move data between systems: rename a field here, reformat a date there, drop a column the target system didn't expect. The logic was always simple but the setup wasn't. I wanted a single tool I could point at a file and a config and just get the output. Remap is that tool.
- CSV → JSON
- JSON → CSV
- CSV → CSV
- JSON → JSON
- Field renaming
- Field dropping
- Type validation:
- int
- float
- date
- string
- Required field validation
- Date parsing with configurable input formats
- Transform system (e.g. upper/lower/date_format)
- Dry-run mode (preview output without writing files)
- Config validation (ensures YAML rules are valid before execution)
go build -o remap ./cmdremap --input data.csv --config remap.yaml --output result.csvremap --input data.csv --config remap.yaml --dry-runmappings:
- from: invoice_date
to: date
type: date
input_date_format: 02-01-2006
transform: date_format(02-01-2006,02/01/2006) #inputFormat, outputFormat
- from: client_name
to: customer
transform: upper()
- from: internal_id
to: ~ # ~ drops the field from outputSource field name in input data.
Output field name.
Use ~ to drop a field.
Marks a field as mandatory.
required: trueDefines validation type:
Supported:
intfloatdatestring
Defines how to parse incoming date strings.
type: date
input_date_format: 02-01-2006Must only be used with type: date.
Defines transformation rules.
Examples:
transform: upper()
transform: lower()
transform: date_format(02/01/2006)Transforms are parsed and applied per field.
Example transformations:
upper()→ converts string to uppercaselower()→ converts string to lowercasedate_format(from, to)→ reformats date strings
Runs before processing data.
Checks:
- valid mapping structure
input_date_formatonly used withtype: date- valid type values
Runs per row of input data.
Checks:
-
required fields exist and are not empty
-
values match declared types:
- int
- float
- date (with configurable layout)
invoice_amount is not a valid float
Dry-run allows previewing output without writing files.
Example:
remap --input data.csv --config remap.yaml --dry-runOutput:
[
{
"date": "01/01/2025",
"customer": "MANNY"
}
]cmd/root.go
internal/
config/ → YAML parsing + config validation
readers/ → CSV / JSON input parsing
mapper/ → transformation engine
transforms/ → transform functions (upper, lower, date_format)
validator/ → record-level validation
writers/ → CSV / JSON output
- Readers are dumb (only parse files)
- Mapper handles one record at a time
- Writers only format output
- Validation happens before transformation
- Config drives all behavior
invoice_date,client_name,internal_id
01-06-2025,Manny,ABC123
mappings:
- from: invoice_date
to: date
type: date
input_date_format: 02-01-2006
transform: date_format(02/01/2006)
- from: client_name
to: customer
transform: upper()
- from: internal_id
to: ~[
{
"date": "01/06/2025",
"customer": "MANNY"
}
]Completed:
- CSV reader
- JSON reader
- CSV writer
- JSON writer
- Mapping engine
- Transform system
- Type validation
- Required field validation
- Date parsing with input format
- Dry-run mode
- Config validation (basic)
- Collect all validation errors (not fail fast)
- Streaming support for large files
- Multiple transforms per field
- Better CLI UX (logs, progress)
- Schema inference mode
- A lightweight Vue-based web preview for non-CLI users