All formats

DBF to JSONdBase (DBF)

Legacy database files.

dBase, FoxPro, and Clipper database tables. TabularJS reads the field definitions and the records, and returns the field types, lengths and header details alongside the rows.

A .dbf file is a database table: a header, one 32-byte descriptor per field (name, type, length, decimals), then fixed-length records. It is the table format of dBase, FoxPro and Clipper, and it is still common in GIS work, because the attribute table of every ESRI shapefile is a .dbf file.

TabularJS reads the header and the records straight from the bytes and returns a worksheet with one column per field and one row per record. A DBF file has no formulas or styles, so the result is the data plus metadata about the table.

Feature support

Data values
Formulas
Styles
Merged cells
Comments
Column metadata

What TabularJS extracts from DBF files

Convert DBF to JSON in Node.js

js
import tabularjs from 'tabularjs';

const result = await tabularjs('products.dbf');
const table = result.worksheets[0];

// One object per record, keyed by field name
const records = table.data.map((row) =>
  Object.fromEntries(table.columns.map((col, i) => [col.name, row[i]]))
);
console.log(records[0]);
// { ID: 1, NAME: 'Café crème', PRICE: 3.5, ACTIVE: true, CREATED: '2026-01-15' }

console.log(table.meta.fields[2]);
// { name: 'PRICE', type: 'N', typeName: 'Numeric', length: 8, decimals: 2, jsType: 'numeric' }

Read DBF files in the browser

js
import tabularjs from 'tabularjs';

const input = document.querySelector('input[type=file]');

input.addEventListener('change', async () => {
  // Override the codepage when the header does not declare it
  const result = await tabularjs(input.files[0], { encoding: 'windows-1251' });
  console.log(result.worksheets[0].data);
});

JSON output

json
{
  "worksheets": [
    {
      "worksheetName": "DBF Data",
      "data": [
        [1, "Café crème", 3.5, true, "2026-01-15"],
        [2, "Croissant", 1.2, false, "2026-01-16"]
      ],
      "columns": [
        { "title": "ID", "name": "ID", "width": 100, "type": "numeric" },
        { "title": "NAME", "name": "NAME", "width": 200, "type": "text" },
        { "title": "PRICE", "name": "PRICE", "width": 100, "type": "numeric", "decimal": "..", "mask": "#,##0.00" },
        { "title": "ACTIVE", "name": "ACTIVE", "width": 100, "type": "checkbox" },
        { "title": "CREATED", "name": "CREATED", "width": 100, "type": "calendar", "options": { "format": "YYYY-MM-DD" } }
      ],
      "meta": {
        "dbfVersion": "dBASE III",
        "totalRecords": 3,
        "activeRecords": 2,
        "deletedRecords": 1,
        "languageDriver": 87,
        "fields": [{ "name": "ID", "type": "N", "typeName": "Numeric", "length": 5, "decimals": 0, "jsType": "numeric" }],
        "deletedRecordIndices": [2]
      }
    }
  ]
}

Output for a three-record dBase III table with one deleted record. meta is trimmed: it also has dbfVersionCode, lastModified, recordLength, headerLength, flags and one fields entry per field.

Options

OptionEffect for DBF
encodingEncoding of the text fields. Default: the codepage of the language driver byte, or Latin-1 when the byte is 0. An unknown name throws Unknown encoding '...'.

Limitations

Frequently asked questions

How do I convert a DBF file to JSON objects?

Use the column names from the field definitions: table.data.map(row => Object.fromEntries(table.columns.map((c, i) => [c.name, row[i]]))). The first row of data is already a record, not a header.

Can I read the attribute table of a shapefile?

Yes. Pass the .dbf file of the shapefile to tabularjs(). You get the attribute rows; the geometry in the .shp file is not read.

Why does a memo field show a number instead of text?

The .dbf file only stores a pointer into a separate memo file (.dbt or .fpt). TabularJS returns that pointer and does not read memo files.

How do I fix garbled characters in text fields?

Pass the codepage the table was written in, for example { encoding: 'cp866' } for Russian DOS files or { encoding: 'windows-1250' } for Central European ones. Without the option, TabularJS uses the codepage declared in the file header.

Are deleted records included?

No. Records marked as deleted are skipped. meta.deletedRecords tells you how many there were and meta.deletedRecordIndices where they were.

Why TabularJS for dBase (DBF)?