# How to Export Data from DBX in CSV Format: CLI, Core Library, and Desktop Methods

> Export DBX data to CSV using CLI, Rust core library, or desktop app. Stream results, format with UTF-8 BOM headers, or write paginated tables directly to disk. Learn three easy methods.

- Repository: [skyler/dbx](https://github.com/t8y2/dbx)
- Tags: how-to-guide
- Published: 2026-07-09

---

**DBX supports CSV export through three integrated layers: a command-line interface that streams results to stdout, a core Rust library that formats query results with UTF-8 BOM headers, and a Tauri-based desktop application that writes paginated table data directly to disk.**

DBX provides robust capabilities to export data from DBX in CSV format across its entire architecture, whether you are using the terminal, building a custom integration, or working within the desktop UI. The `t8y2/dbx` repository implements this functionality through complementary layers that share common escaping logic and NULL handling rules. Each layer is optimized for its specific environment while maintaining consistent output formatting.

## Export Methods Overview

### Command-Line Interface (CLI) Export

The CLI layer formats query results, connection lists, and schema information as CSV on-the-fly. In [`packages/cli/src/cli-format.ts`](https://github.com/t8y2/dbx/blob/main/packages/cli/src/cli-format.ts), the `csvTable()` function builds the text representation, while [`packages/cli/src/cli.ts`](https://github.com/t8y2/dbx/blob/main/packages/cli/src/cli.ts) parses the `--format csv` flag to trigger this behavior. When you run a query with the CSV format flag, DBX executes the SQL and pipes the formatted result directly to stdout, allowing you to redirect the output to a file using standard shell operators.

### Core Library Programmatic Export

The Rust core library handles the low-level CSV generation in [`crates/dbx-core/src/csv_export.rs`](https://github.com/t8y2/dbx/blob/main/crates/dbx-core/src/csv_export.rs). The `format_query_result_csv()` function converts generic query results into properly escaped CSV strings, prefixing the output with a UTF-8 BOM (`\u{FEFF}`) for Excel compatibility. This layer handles NULL values distinctly: query results render NULL as the string `"NULL"`, while standard CSV exports use empty cells. The function relies on `escape_csv()` to handle field quoting and internal quote doubling.

### Desktop Application (Tauri) Export

For the desktop UI, Tauri commands in [`src-tauri/src/commands/csv_export.rs`](https://github.com/t8y2/dbx/blob/main/src-tauri/src/commands/csv_export.rs) provide file-system integration. The `export_query_result_csv` and `export_table_data_csv` commands receive a file path from the frontend and stream data to disk using `BufWriter`. The `export_table_data_csv_core()` function in the core library paginates large tables using `build_table_data_select_sql()`, writes the BOM once, and processes each page through `write_csv_row()`, ensuring memory-efficient exports of large datasets.

## The CSV Export Pipeline

### From Query to File

The export process follows a consistent pipeline across all interfaces. First, the system executes the SQL statement using `execute_sql_statement_with_options`. Then, the result columns and rows pass through `format_query_result_csv()`, which builds the header row by applying `escape_csv()` to each column name. For data rows, the system converts each `serde_json::Value` into CSV-compatible text using `value_to_query_result_csv_text()`, joining rows with newline characters and prefixing the entire output with the UTF-8 BOM.

### NULL Handling and Field Escaping

DBX implements strict NULL handling rules to ensure data integrity. In query result exports, NULL values appear as the literal string `"NULL"` in the output, while table exports leave the cell empty. The `escape_csv()` function manages RFC 4180 compliance by wrapping fields containing commas, quotes, or newlines in double quotes, and doubling internal quotes to prevent parsing errors.

## Practical Code Examples

Export a query directly to a CSV file using the CLI:

```bash
dbx query local "SELECT id, name FROM users ORDER BY id" --format csv > users.csv

```

Use the Node.js core library to format query results as CSV:

```typescript
import { format_query_result_csv } from '@dbx-app/node-core';

const columns = ['id', 'name'];
const rows = [
  [{ id: 1 }, { name: 'Ada' }],
  [{ id: 2 }, { name: 'Bob' }],
];

const csv = format_query_result_csv(columns, rows);
console.log(csv);   // prints a BOM‑prefixed CSV string

```

Export an entire table from the Desktop application (Rust internals):

```rust
// This represents the internal call structure used by the Tauri command
export_table_data_csv_core(
    connection_id,
    TableCsvExportOptions {
        file_path: "/tmp/orders.csv".into(),
        database: "mydb".into(),
        schema: None,
        table_name: "orders".into(),
        columns: vec![],          // empty → export all columns
        page_size: Some(5000),   // optional paging size
        timeout_secs: Some(30),
    }
)

```

Generate CSV internally within a CLI extension:

```typescript
import { csvTable } from '@dbx-app/cli';

const headers = ['id', 'name'];
const data = [{ id: 1, name: 'Ada' }, { id: 2, name: 'Bob' }];
const csv = csvTable(headers, data);
process.stdout.write(csv);

```

## Summary

- DBX provides three export layers: CLI (`csvTable()` in [`cli-format.ts`](https://github.com/t8y2/dbx/blob/main/cli-format.ts)), Core library (`format_query_result_csv()` in [`csv_export.rs`](https://github.com/t8y2/dbx/blob/main/csv_export.rs)), and Desktop (`export_table_data_csv` in Tauri commands).
- All layers share `escape_csv()` logic and prefix output with a UTF-8 BOM (`\u{FEFF}`) for Excel compatibility.
- The CLI streams results to stdout using the `--format csv` flag, while the Desktop interface paginates large tables via `export_table_data_csv_core()` and writes directly to disk.
- NULL handling differs between query results (rendered as `"NULL"`) and standard table exports (empty cells).
- Key files: [`crates/dbx-core/src/csv_export.rs`](https://github.com/t8y2/dbx/blob/main/crates/dbx-core/src/csv_export.rs) contains the core logic; [`src-tauri/src/commands/csv_export.rs`](https://github.com/t8y2/dbx/blob/main/src-tauri/src/commands/csv_export.rs) handles the desktop API; [`packages/cli/src/cli-format.ts`](https://github.com/t8y2/dbx/blob/main/packages/cli/src/cli-format.ts) manages CLI formatting.

## Frequently Asked Questions

### How do I export a large table to CSV without running out of memory?

The Desktop export method uses `export_table_data_csv_core()` in [`crates/dbx-core/src/csv_export.rs`](https://github.com/t8y2/dbx/blob/main/crates/dbx-core/src/csv_export.rs), which implements pagination via `build_table_data_select_sql()`. It processes data in configurable chunks (defaulting to 5000 rows) and streams each page to a `BufWriter`, ensuring constant memory usage regardless of table size.

### Why does my exported CSV file start with strange characters?

The DBX core library intentionally prefixes every CSV export with a UTF-8 Byte Order Mark (`\u{FEFF}`) as implemented in `format_query_result_csv()`. This mark ensures Microsoft Excel and other applications correctly interpret the file as UTF-8 encoded, preventing character corruption in international datasets.

### Can I export query results programmatically from Node.js?

Yes. The `@dbx-app/node-core` package exposes `format_query_result_csv()`, which accepts column names and rows as `serde_json::Value` objects and returns a complete CSV string. This function handles all escaping and BOM insertion automatically, matching the output of the CLI and Desktop versions.

### How does the CLI handle NULL values compared to the Desktop export?

In the CLI query results processed by `format_query_result_csv()`, NULL values appear as the literal string `"NULL"` in the CSV output. Conversely, when using the Desktop's table export via `export_table_data_csv()`, NULL values result in empty cells. This distinction ensures query results preserve semantic NULL information while table exports maintain compatibility with standard CSV consumers.