Build a command-line file conversion tool using Node.js. Learn to handle file I/O, parse arguments, convert between formats like CSV to JSON, and publish your tool to npm.
In this tutorial, you will build a CLI tool called fconv that converts files between common formats:
By the end, you will have a reusable, publishable npm package that runs from the terminal:
fconv input.csv --to json -o output.json
Create a new project directory and initialize it:
mkdir fconv && cd fconv
npm init -y
Install the dependencies we need:
npm install commander csv-parse csv-stringify js-yaml marked
Update package.json to add the bin entry:
{
"bin": {
"fconv": "./index.js"
},
"type": "module"
}
Mentioned in this article — free, no sign-up required.
Create index.js with the argument parser:
#!/usr/bin/env node
import { Command } from "commander";
import { readFileSync, writeFileSync } from "fs";
import { convert } from "./converter.js";
const program = new Command();
program
.name("fconv")
.description("Convert files between formats")
.argument("", "Input file path")
.requiredOption("--to ", "Output format (json, csv, html, yaml)")
.option("-o, --output ", "Output file path")
.option("-p, --pretty", "Pretty print output", false)
.action((input, options) => {
const content = readFileSync(input, "utf-8");
const result = convert(content, input, options.to, options.pretty);
if (options.output) {
writeFileSync(options.output, result);
console.log(Converted: ${input} -> ${options.output});
} else {
console.log(result);
}
});
program.parse();
Create converter.js with the conversion logic:
import { parse } from "csv-parse/sync";
import { stringify } from "csv-stringify/sync";
import yaml from "js-yaml";
import { marked } from "marked";
import { extname } from "path";
export function convert(content, inputPath, toFormat, pretty) {
const fromFormat = extname(inputPath).slice(1).toLowerCase();
const key = ${fromFormat}->${toFormat};
const converters = {
"csv->json": () => {
const records = parse(content, { columns: true, trim: true });
return JSON.stringify(records, null, pretty ? 2 : 0);
},
"json->csv": () => {
const data = JSON.parse(content);
return stringify(data, { header: true });
},
"md->html": () => marked(content),
"yaml->json": () => {
const data = yaml.load(content);
return JSON.stringify(data, null, pretty ? 2 : 0);
},
"json->yaml": () => yaml.dump(JSON.parse(content)),
};
const fn = converters[key];
if (!fn) throw new Error(Unsupported conversion: ${key});
return fn();
}
Link the tool locally to test it:
npm link
Create a test CSV file test.csv:
name,age,city
Alice,30,New York
Bob,25,London
Charlie,35,Tokyo
Run the conversions:
# CSV to JSON
fconv test.csv --to json -p
# Output:
[
{ "name": "Alice", "age": "30", "city": "New York" },
{ "name": "Bob", "age": "25", "city": "London" },
{ "name": "Charlie", "age": "35", "city": "Tokyo" }
]
Save to a file:
fconv test.csv --to json -p -o test.json
To share your tool with the world:
npm loginnpm publish
Anyone can now install and use your converter:
npx fconv data.csv --to json -p
Absolutely. Just add a new entry to the converters object in converter.js. The pattern is "from->to": () => convertedString.
For files over 100 MB, use streaming instead of readFileSync. Both csv-parse and csv-stringify support Node.js streams.
This tool focuses on text-based formats. For binary conversions, use Reformat's free online tools which handle PDF, images, and more.