npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

flat-file-creator

v3.0.3

Published

Generate a flat positional text file of your dataset

Readme

flat-file-creator

Read and write fixed-width flat files from typed TypeScript data — the boring format your bank still loves, made painless.

Version support

  • v3.x — current stable version (npm install flat-file-creator), see Migration Guide
  • v2.x — maintenance, security fixes only (npm install flat-file-creator@v2)

Install

npm install flat-file-creator

Requirements: Node.js ≥ 20, ESM project ("type": "module" or .mjs files).


Quick start

import { getAsyncFlatFileCreator, getAsyncFlatFileReader } from 'flat-file-creator'

// 1. Describe the row layout
const fields = [
  { name: 'firstName', type: 'string',  size: 20 },
  { name: 'lastName',  type: 'string',  size: 20 },
  { name: 'dob',       type: 'date',    size: 24, format: { utc: true } },
  { name: 'score',     type: 'float',   size: 8,  precision: 2 },
]

// 2. Create writer and reader from the same definition
const writeFile = getAsyncFlatFileCreator(fields)
const readFile  = getAsyncFlatFileReader<Person>(fields)

// 3. Write
await writeFile(
  [
    { firstName: 'Jo',    lastName: 'Revelo',     dob: new Date('1986-01-01'), score: 9.75 },
    { firstName: 'Ricky', lastName: 'Springfield', dob: new Date('1975-06-15'), score: 8.50 },
  ],
  '/tmp/people.txt',
)

// 4. Read back — `rows` is fully typed as Person[]
const rows = await readFile('/tmp/people.txt')
console.log(rows[0].dob.getFullYear()) // 1986

Field types

Every field needs at minimum name and size. The type defaults to 'string' when omitted.

string

{ name: 'city', type: 'string', size: 30 }

| Option | Type | Default | Description | |---|---|---|---| | paddingPosition | 'start' \| 'end' | 'end' | Where to add padding | | paddingSymbol | string | ' ' | Character used for padding | | preserveEmptySpace | boolean | false | Skip trimming whitespace | | straight | boolean | false | Throw if value is numeric | | enum | { [key: string]: string } | — | Serialize/deserialize a set of values | | default | string \| null | — | Fallback when value is missing |

integer

{ name: 'age', type: 'integer', size: 5 }

Integers are left-padded with spaces by default. All standard CommonSpec options apply.

float

{ name: 'score', type: 'float', size: 8, precision: 2 }

| Option | Type | Default | Description | |---|---|---|---| | precision | number | 0 | Decimal places | | dotNotation | boolean | false | When false, value is stored as integer × 10^precision |

Example9.75 with precision: 2, dotNotation: false" 975", and back to 9.75 on read.

date

{ name: 'dob', type: 'date', size: 24, format: { utc: true, dateFormat: 'yyyy-MM-dd' } }

| Option | Type | Default | Description | |---|---|---|---| | format.dateFormat | string | ISO 8601 | date-fns format tokens | | format.utc | boolean | false | Format in UTC | | default | Date \| string \| null | — | Fallback when value is missing |

On read, date fields are always returned as native Date objects.


API

function getAsyncFlatFileCreator(
  maps: Array<FieldSpec>,
  options?: Partial<WriteOptions>
): (dataRows: Array<RowData>, filePath: string) => Promise<void>

function getAsyncFlatFileReader<T>(
  maps: Array<FieldSpec>,
  options?: Partial<ReadOptions>
): (filePath: string) => Promise<Array<T>>

Note: rows are always written in the same order as the input array. Each call to the returned writer opens the file, streams all rows sequentially, then closes it.


Options

Both getAsyncFlatFileCreator and getAsyncFlatFileReader accept an optional second argument:

interface ReadOptions {
  rowEnd?:      string          // line terminator, default ''
  encoding?:    BufferEncoding  // default 'utf8'
  throwErrors?: boolean         // throw on structural errors, default true
}

interface WriteOptions extends ReadOptions {
  mode?:        number          // file mode, default 0o666
  flag?:        string          // fs flag, default 'a' (append)
}

Type definitions

type RowData = { [fieldName: string]: string | number | boolean | Date | null | undefined }

type CommonSpec = {
  name:             string
  size:             number
  paddingPosition?: 'start' | 'end'
  paddingSymbol?:   string
  desc?:            string
}

type StringFieldSpec = CommonSpec & {
  type?:               'string'
  enum?:               { [serializedKey: string]: string }
  preserveEmptySpace?: boolean
  straight?:           boolean
  default?:            string | null
}

type IntegerFieldSpec = CommonSpec & {
  type:     'integer'
  default?: number | null
}

type FloatFieldSpec = CommonSpec & {
  type:          'float'
  precision?:    number
  dotNotation?:  boolean
  default?:      number | null
}

type DateFieldSpec = CommonSpec & {
  type:     'date'
  format?:  { utc?: boolean; dateFormat?: string }
  default?: Date | string | null
}

type FieldSpec = StringFieldSpec | IntegerFieldSpec | FloatFieldSpec | DateFieldSpec

Working with lines directly

If you prefer to work with strings instead of files, two lower-level helpers are available:

import { dataToLines, linesToData } from 'flat-file-creator'

const lines = dataToLines(rows, fields)       // string[]
const rows  = linesToData(lines.join('\n'), fields) // T[]

Migrating from v2 to v3

v3 is a clean break. If you can't migrate yet, v2.x stays available and receives security fixes.

npm install flat-file-creator      # v3, current stable
npm install flat-file-creator@v2   # stay on v2

1. Node.js ≥ 20 required

v2 supports Node.js 10+. v3 requires Node.js 20 or later.

2. Pure ESM — no CommonJS support

v3 is a pure ESM package and cannot be require()'d. If your project is still on CommonJS and cannot migrate, stay on v2.

// v3 — ESM only
import { getAsyncFlatFileCreator } from 'flat-file-creator'

3. moment removed — date format tokens changed

v3 replaces moment with date-fns. Update your dateFormat tokens:

| v2 (moment) | v3 (date-fns) | |---|---| | YYYY | yyyy | | DD | dd | | HH, mm, ss | unchanged |

// v2
{ type: 'date', format: { dateFormat: 'DD/MM/YYYY' } }

// v3
{ type: 'date', format: { dateFormat: 'dd/MM/yyyy' } }

4. Moment type removed from DateFieldValue

DateFieldValue no longer accepts moment objects:

// v2
import moment from 'moment'
const dob = moment('1986-01-01')

// v3
const dob = new Date('1986-01-01')  // or just '1986-01-01'

5. Date fields return Date instead of Moment

// v2
rows[0].dob.year()        // moment API

// v3
rows[0].dob.getFullYear() // native Date API

6. getAsyncFlatFileCreator return type changed

The writer now returns Promise<void> instead of Promise<string[]>. The previous return value was an array of file paths (one per row) with no practical use. If your code consumed it, remove it:

// before
const result = await writeFile(rows, '/tmp/out.txt') // result was string[]

// after
await writeFile(rows, '/tmp/out.txt')

Row ordering is now guaranteed — rows are always written in the same order as the input array. If your code worked around the previous non-deterministic ordering, that workaround can be removed.