JCSV file format Version 1.1

Documentation •
Dans cet article

JCSV is a UTF-8, line-oriented JSON format for storing tabular data together with metadata. Each JCSV record is written on a separate physical line as a complete JSON value. Metadata and control information are encoded as JSON objects, while tabular data rows are encoded as JSON arrays.

Unlike traditional CSV, JCSV can include multiple tables or structured data sections in a single document, making it suitable for software interoperability, AI-assisted data analysis, and long-term data archival.

Version 1.1 is an evolution of JCSV 1.0. It is still under development and introduces features intended to make the format more AI-friendly, self-descriptive, and reliable for preserving reusable data over time.

Naming

JCSV stands for JSON CSV. The name reflects the purpose of the format: to preserve the simplicity and line-oriented nature of CSV while using JSON syntax to represent both metadata and data values in a structured and unambiguous way.

Example of a JCSV and CSV equivalent 

This is a typical CSV file with Accounts information and balance

Account,Description,Balance
1000,Cash on hand,1290.3
1020,Bank account,10
2000,Suppliers,-10

and the JCSV equivalent, where the "columnNames" metadata line contains the list of columns in the sequence of the data..

{"jcsv":{"version":"1.1"}}

{"document":{"topic":"Financial Data","region":"General"}}

{"table":{"name":"Accounts","header":"Accounts"}}
{"columnNames":["Account","Description","Balance"]}
["1000","Cash on hand",1290.3]
["1020","Bank account",10]

["2000","Suppliers",-10]

JCSV principles

A JCSV file is composed of physical lines. Each JCSV record is written on one line and is either a metadata line or a data line.

  • Metadata lines are valid JSON objects. They contain metadata, declarations, or control information. 
    For example, jcsv, document, table, columnNames, and columns are metadata lines.
  • Data lines are valid JSON arrays. 
    • They contain tabular values in the same sequence defined by the current columnNames line.
    • A data line represents one tabular row.

Empty lines are ignored. In permissive reading mode, other non-JCSV text lines may also be ignored. In strict validation mode, non-empty lines that are not valid JSON objects or JSON arrays are errors.

All JCSV records are valid JSON values, so parsing does not depend on separators, quoting conventions, or locale-specific parameters.

The JCSV file structure

A JCSV file may contain file-level metadata, semantic sections, and one or more table sections.

  • Metadata regarding the file
    • jcsv: required. Identifies the content as a JCSV file and declares the format version.
    • generator: optional. Contains information about the application that generated the file.
    • document: optional. Contains information about the document.
    • semantics: optional. Contains information that helps interpret the data.
  • Table metadata and data
    A JCSV file may contain one or more table sections.
    • table: required for named table sections. Starts a new table section and contains table-level metadata.
    • columnNames: required for table data. Contains the list of columns and their sequence.
    • columns: optional. Contains additional information about the columns.
    • Data lines
      • One or more JSON arrays containing the actual data. 
      • Data lines may be preceded by optional row-level metadata, such as rowStyle or rowErrors.

JCSV Example with Atmospheric Observations

This is a more complete JCSV example that contains information about atmospheric observations. There are two tables, "Locations" and "Observations". The "semantics" section contains information that allows the AI to correctly interpret values, such as the unit "mm" for rainfall and the source reference for "Locations.StationId".

/* text that is not within {} or [] is ignored */ 
{"jcsv" : {"version" : "1.1", "encoding":"UTF-8"}} 
{"generator":{"createdAt":"2026-05-06T09:00:00Z","name":"MeteoLink-Pro","version":"2.4.0"}} 
{"document":{"region":"Lugano, Switzerland","stationId":"LUG-S01","topic":"Atmospheric Observations","coordinates":{"lat":46.0037,"lon":8.9511}}} 

{"semantics":{"description":"Semantic information for interpreting weather data","type":"table"}} 
{"columnNames":["TableName","ColumnName","Role","Reference","Unit","Description"]}
["Observations","Timestamp","PrimaryKey","","ISO-8601","Unique temporal identifier for the reading"] 
["Observations","Temp","ObservationValue","","°C","Air temperature at 2 meters altitude"] 
["Observations","Rainfall","ObservationValue","","mm","Cumulative precipitation for the hour"] 
["Observations","StationStatus","StatusFlag","","","Indicates if the sensor was operating within parameters"] 
["Observations","Source","SourceReference","Locations.StationId","","Links data to the station ID in the locations table"]
["Locations","StationId","PrimaryKey","","","Unique identifier for the weather station"]
["Locations","Name","Context","","","Natural language name of the site"]
["Locations","Altitude","Measurement","","m s.l.m.","Elevation above sea level"]
["Locations","Lat","Coordinate","","decimal","Latitude"]
["Locations","Lon","Coordinate","","decimal","Longitude"]

{"table":{"name":"Locations","header":"Monitoring Stations Locations"}}
{"columnNames":["StationId","Name","Altitude","Lat","Lon"]}
{"columns":[{"name":"StationId","type":"string"},{"name":"Name","type":"string"},{"name":"Altitude","type":"number"},{"name":"Lat","type":"number","decimalPlaces":4},{"name":"Lon","type":"number","decimalPlaces":4}]}
["LUG-S01","Lugano Centro",273,46.0037,8.9511]
["LUG-S02","Monte Brè",925,46.0061,8.9831]

{"table":{"name":"Observations","header":"Weather Observations hourly"}}
{"columnNames":["Timestamp","Temp","Rainfall","StationStatus","Source"]} 
{"columns":[{"name":"Timestamp","type":"date"},{"name":"Temp","type":"number","decimalPlaces":1},{"name":"Rainfall","type":"number","decimalPlaces":2},{"name":"StationStatus","type":"string"},{"name":"Source","type":"string"}]}
["2026-05-06T07:00:00Z",14.2,0.00,"OK","LUG-S01"] 
["2026-05-06T08:00:00Z",15.8,0.00,"OK","LUG-S01"] 
["2026-05-06T09:00:00Z",16.1,0.45,"WARNING","LUG-S01"]

 

Why JCSV is AI-friendly

JCSV is more self-descriptive than CSV, simpler than XML, more readable than binary formats, and better suited to complex tabular data than a single large nested JSON file.

  • Unambiguous parsing: unlike CSV, JCSV does not depend on field separators, quoting rules, empty lines, or locale-specific conventions.
  • Explicit column order: columnNames clearly maps array values to column names.
  • Multiple tables in one file: related data can stay together instead of being split across many CSV files.
  • Rich metadata support: columns can describe types, formats, constraints, decimals, and descriptions.
  • Semantic layer: semantics can explain roles, relationships, keys, references, units, and meanings.
  • Less ambiguity: AI does not need to guess what columns or codes represent.
  • Lower computational overhead: explicit structure and semantics can reduce inference, clarification, and error-correction work during AI-assisted analysis.
  • Line-oriented structure: each line is either metadata {} or data [], making parsing simple and predictable.
  • Plain text format: easy for AI systems to read, inspect, and reason about.
  • Stream-friendly: files can be processed sequentially, even when large.
  • Human-readable: both humans and AI can understand the file without specialized binary tools.
  • Good balance: combines the simplicity of CSV with the context usually missing from CSV.

Why JCSV is suitable for long-term data preservation

  • Plain text format: data remains readable without depending on a specific application or binary format.
  • Based on JSON syntax: uses a widely known, stable, and well-supported data representation.
  • Unambiguous parsing: avoids common CSV issues such as separators, quoting rules, empty lines, and locale-dependent formatting.
  • Self-describing structure: metadata, table names, columnNames, and optional columns help future users understand the file.
  • Multiple tables in one file: related datasets can be preserved together, reducing the risk of losing context between separate files.
  • Reusable by data-management applications: tables, column names, metadata, and relationships can be imported or mapped into databases, spreadsheets, ETL tools, and analysis software.
  • Semantic information: semantics can document roles, relationships, references, units, and meanings that might otherwise be lost.
  • Human-readable: future users can inspect the file with a simple text editor.
  • Software-independent: the file can be interpreted without the original program that created it.
  • Versionable: the jcsv metadata can include a format version, helping future parsers apply the correct rules.
  • Stable for archival workflows: the line-oriented structure is easy to validate, diff, store, compress, and checksum.
  • Good balance: combines the longevity of plain text with more structure and context than traditional CSV.

JCSV format specification

See example below.

  • UTF-8 character encoding.
    The UTF-8 encoding is mandatory. 
  • Line-delimited JSON format in which each physical line contains one complete JSON value.
    • Line endings must use LF, Line Feed, U+000A ("\n"). 
      Readers should also support CRLF, U+000D U+000A ("\r\n"), for compatibility, but a standalone CR, U+000D ("\r"), must not be considered a valid line break.
    • Writers should always emit LF line endings and omit CR characters.
    • LF must be used only to terminate physical lines and must not occur unescaped inside a data or metadata line. If a text value requires an internal line break, it should use LS, Line Separator, U+2028, or another appropriate application-defined replacement or escaping convention.
  • Metadata lines
    • Meta data line start "{" and end with the  "}" brackets.
    • A metadata line is a valid JSON object encoded on a single physical line. 
    • It contains one top-level JCSV property.
    • The value of the property depends on the metadata type. 
      • Most metadata properties, such as jcsv, document, generator, table, rowStyle, and rowErrors, use a nested JSON object. 
      • Some properties, such as columnNames, use a JSON array.
    • Whitespace inside a metadata line is allowed by JSON, but writers should prefer compact JSON and must not insert physical line breaks inside a JCSV record.
    • Metadata lines usually apply to the records that follow them. 
      • For example, a table line starts a table section, and the following data lines belong to that table until another table, document, or section declaration is found.
      • Row-level metadata, such as rowStyle or rowErrors, applies only to the next data line unless otherwise specified.
    • Reserved metadata keywords:
      • Standard JCSV property names use lower camelCase (for example: rowStyle, fontSize). 
      • Property names are case-sensitive.
      • "jcsv" is required and should be the first JCSV record. 
        • It identifies the file as JCSV and declares the format version. 
        • The version property is required. 
        • The encoding property is optional and, when present, must be "UTF-8".
      • "generator" contains information regarding the application that has generated the file.
      • "document" contains information regarding the file.
        • Add any element that may be helpful to understand the data, like name, header, description, etc.
        • All successive elements before the next "document" should be belonging to this document.
      • "semantics" is a table element containing information that help interpret the content.
        • The semantics metadata line may introduce a semantic table. 
          If followed by columnNames and data lines, those lines belong to the semantics section until the next table, document, or other section declaration.
        • The semantics section is similar to a table, but has its own tag to avoid conflict with a possible user table named "semantics"
      • "comment" for entering comments
      • "schema" reserved keyword for later use. 
      • "provenance" information regarding the provenance of the data. It can be used at the document or the table level.
      • "table" contains the name of a table.
        • Add any element that may be helpful to understand the data, like name, header, description, etc.
        • All rows following the "table" are considered to belong to this table.
        • A table section continues until the next table declaration, the next document declaration, or the end of the file.
      • "columnNames" is a mandatory element that contains a JSON Array with the columns names.
        The data rows following the columns are considered to be in the sequence of the columns name.
        A "columnNames" that does not follow a "table" is considered to start a new table.
      • "columns" contains information relative to the columns.
        The columns information is not necessarily in the sequence of the data, so the  "columnNames" should always be present.
      • "rowErrors" contains information regarding errors at the row level.
        • line applies only to the next data line.
      • "rowStyle" contains supplementary information regarding the following data row.
        • line applies only to the next data line.
      • Custom metadata. 
        • It is possible to add application-specific properties. 
        • Possibly use lower camelCase unless a namespace or extension convention defines otherwise.
  • Data lines.
    Data lines contain the actual tabular data. 
    • They should be preceded by the "table" and "columnNames".
    • A data line is a JSON array encoded on a single physical line. 
    • The line starts with the "[" and terminate with the "]" .
    • The number of elements within the array must be the same size as the preceding "columnNames".
    • Data is stored in JSON format.
      • Strings are enclosed in double quotes.
        • Usual string "Bank account".
      • Date, Time and Timestamp are JSON string in the ISO date format 8601
        • Date  "2018-01-03".
        • Time "10:18:21.000".
        • Timestamp "2016-11-19T09:52:39".
      • Number in valid JSON format, decimal separator "."
      • true or false.
      • null.
  • Empty lines are allowed, but not considered.
  • Other lines not being a valid JSON Object or not an empty line are considered an error.
    • Strict mode: invalid/non-JCSV lines are errors.
    • Permissive mode: empty and non-JCSV text lines may be ignored.
    • Formal comments should be encoded using the comment metadata property.
      {"comment":{"text":"This file contains atmospheric observations."}}

JCSV files

  • Proposed  media type: text/jcsv.
    • Until formally registered, implementations may use application/x-jcsv or text/plain with the .jcsv extension.
  • File extension ".jcsv".
  • Encoding "UTF-8".

JCSV export in Banana Accounting

You can try a new format by installing the Banana Accounting software.

  • See JCSV example files on Github\BananaAccounting
  • Open or drag a JCSV file in Banana
    Banana will create a new file tables and columns. You can then copy and paste the data in Excel.
  • Export in JCSV 
    • Export of a single table
      Menu Data -> Export Rows->JCSV 
    • Export of all the tables
      Menu File -> Export ->JCSV

Programmatically Generating the JCSV

To generate a JCSV file, you can use the JSON functions that each programming language provides. This makes it much easier and simpler than creating a CSV file.

  1. Create a JSON object that contains a JSON array with the column names, convert it to JSON text, and add a line feed.
  2. For each data row, create a JSON array that contains the data, convert it to JSON text, and add a line feed.

The following is a simple example in JavaScript that uses JSON.stringify.

// JavaScript: Create a JCSV document

var text = "";

// JCSV format declaration
text += JSON.stringify({ "jcsv": { "version": "1.1" } }) + "\n";

// Document metadata
text += JSON.stringify({ "document": { "topic": "Financial Data", "region": "General" } }) + "\n";

// Table declaration
text += JSON.stringify({ "table": { "name": "Accounts", "header": "Accounts" } }) + "\n";

// Column names
text += JSON.stringify({ "columnNames": ["Account", "Description", "Balance"] }) + "\n";

// Data rows
text += JSON.stringify(["1000", "Cash on hand", 1290.3]) + "\n";
text += JSON.stringify(["1020", "Bank account", 10]) + "\n";
text += JSON.stringify(["2000", "Suppliers", -10]) + "\n";

console.log(text);

Parse the JCSV file

  1. Read each line.
    • If a line starts with "{" and ends with "}", parse it as JSON and extract the values. The "table" object marks the start of a new table.
    • The "columnNames" object contains the list and sequence of the CSV data that follows.
  2. If a line starts with "[" and ends with "]", parse it as JSON and extract the data.
     

Simple JCSV parser

/* JavaScript to read a JCSV, separate Metadata with data */
var lines = text.split(/\r?\n/);

for (var i = 0; i < lines.length; i++)
{
  var line = lines[i].trim();
  // Metadata or control lines
  if (line.startsWith("{") && line.endsWith("}"))
  {
    var object = JSON.parse(line);
    console.log("Metadata line:", object);
  }
  // Data rows
  if (line.startsWith("[") && line.endsWith("]"))
  {
    var row = JSON.parse(line);
    console.log("Data row:", row);
  }
  // Empty lines or other lines are ignored
}

Parsing the JCSV Atmospheric Observations

This JavaScript reads the JCSV Atmospheric Observations and extracts and prints the observation data in JSON format.

// JavaScript: Read JCSV data and create a JSON object with the Observations table

var lines = text.split(/\r?\n/);
var currentTable = "";
var columnNames = [];
var observations = [];

for (var i = 0; i < lines.length; i++) {
  var line = lines[i].trim();

  if (!line.startsWith("{") && !line.startsWith("[")) {
    continue;
  }

  var value = JSON.parse(line);

  if (value.table) {
    currentTable = value.table.name;
  }
  else if (value.columnNames) {
    columnNames = value.columnNames;
  }
  else if (Array.isArray(value) && currentTable === "Observations") {
    var observation = {};

    for (var j = 0; j < columnNames.length; j++) {
      observation[columnNames[j]] = value[j];
    }

    observations.push(observation);
  }
}

console.log(JSON.stringify(observations, null, 2));

/* Result in JSON format
[
  {
    "Timestamp": "2026-05-06T07:00:00Z",
    "Temp": 14.2,
    "Rainfall": 0,
    "StationStatus": "OK",
    "Source": "LUG-S01"
  },
  {
    "Timestamp": "2026-05-06T08:00:00Z",
    "Temp": 15.8,
    "Rainfall": 0,
    "StationStatus": "OK",
    "Source": "LUG-S01"
  },
  {
    "Timestamp": "2026-05-06T09:00:00Z",
    "Temp": 16.1,
    "Rainfall": 0.45,
    "StationStatus": "WARNING",
    "Source": "LUG-S01"
  }
]
*/ 

 

Author

The JCSV specification was conceived and developed by Domenico Zucchetti, founder and CEO of Banana.ch and creator of Banana Accounting, in 2016. Its aim was to create a format that could be as simple as CSV but contain more data across multiple tables and be parsed without ambiguity. He developed the line-based text format using JSON elements. He then implemented the export function in Banana Accounting using the JCSV format, both for single tables and for complete accounting data. The format proved very useful for sharing accounting data with other systems.

In April 2026, a colleague informed Domenico that the JCSV format was well understood by AI tools, thanks to its simple structure and the possibility of combining metadata and data. We envisioned the possibility of passing the entire accounting data to an AI engine to analyse the information. We reworked the JCSV format to remove some inconsistencies and make it more AI-friendly. We also understood that the typical information used to define the database was not sufficient to fully understand the data and extract information from it. We also considered the case of reusing the data after a long period of storage. It became clear that the possibility of mixing metadata with data within the same file could make it possible to add semantic information, which could better explain the content and the relations between the data. The results obtained seemed very promising, so we published JCSV version 1.1, with the idea that it could be the first step toward further testing and improvements to the format.
 

Domenico Zucchetti has more than 40 years of experience in international accounting, as well as experience as a legal expert and software developer. He has been a blockchain pioneer. In 2002, he was the first in the world to implement a blockchain certification feature in accounting software.

D. Zucchetti welcomes feedback.

 

 

Comment pouvons-nous mieux vous aider ?

Dites-nous quel sujet nous devrions développer ou ajouter pour rendre cette page plus utile.

Envoyez-nous vos commentaires

Partager cet article: Twitter | Facebook | LinkedIn | Email