Blog

Luis Majano

October 30, 2025

Spread the word


Share your thoughts

We're thrilled to announce the release of bx-csv, a powerful premium module that brings enterprise-grade CSV processing capabilities to BoxLang+ subscribers! Built on Apache Commons CSV, this module provides both traditional functions and a modern, fluent API that makes working with CSV files a breeze.

✨ What's New?

The bx-csv module transforms how you work with CSV files in BoxLang, offering:

  • 🚀 Modern Fluent API - Chainable, elegant code that's easy to read and maintain
  • Streaming Support - Process massive files without memory concerns
  • 🎯 Smart Data Transformation - Built-in filtering and mapping during load operations
  • 📦 Multi-Format Support - Seamless conversion between CSV, JSON, Query, and arrays
  • 🎨 Flexible Configuration - Custom delimiters, quotes, escapes, and line separators
  • 💪 Production Ready - Battle-tested Apache Commons CSV foundation

🎟️ Subscription & Trial Information

The bx-csv module is available exclusively to BoxLang+ and BoxLang++ subscribers. However, we want everyone to experience its power, so it comes with a generous 60-day trial when installed alongside the bx-plus module.

Ready to try it? Install it now:

box install bx-csv

Not a subscriber yet? Check out our plans and start your trial today!


🚀 The Modern Way: Fluent API

We've designed the fluent API to be intuitive and powerful. Here's how easy it is to create and manipulate CSV files:

Creating a CSV File

// Create a simple contacts file
CSV()
    .setHeaders( "Name", "Email", "Age" )
    .addRow( [ "John Doe", "john@example.com", 30 ] )
    .addRow( [ "Jane Smith", "jane@example.com", 25 ] )
    .addRow( [ "Bob Johnson", "bob@example.com", 35 ] )
    .save( "contacts.csv" );

That's it! Clean, readable, and maintainable. The fluent API chains methods together, making your intent crystal clear.

Loading and Transforming Data

// Load, filter, and transform in one elegant chain
CSV( "raw-data.csv" )
    .filter( ( row ) => {
        // Only include rows with valid emails
        return row[ 2 ].find( "@" ) > 0;
    } )
    .map( ( row ) => {
        // Normalize the data
        row[ 0 ] = row[ 0 ].trim().toUpperCase(); // Name
        row[ 1 ] = row[ 1 ].trim(); // Phone
        row[ 2 ] = row[ 2 ].trim().toLowerCase(); // Email
        return row;
    } )
    .save( "cleaned-data.csv" );

⚡ Streaming Large Files

One of the most powerful features is the ability to process huge files without loading them entirely into memory:

// Process a multi-gigabyte file efficiently
CSV().process( "huge-file.csv", ( row ) => {
    // Process each row individually
    queryExecute(
        "INSERT INTO customers (name, email) VALUES ( ?, ? )",
        [ row[ 1 ], row[ 2 ] ]
    );
} );

The streaming API ensures your application remains responsive even when processing files with millions of rows.

📊 Seamless Format Conversion

The bx-csv module makes it trivial to convert between different data formats:

From Database to CSV

// Export query results directly to CSV
qData = queryExecute( "
    SELECT
        customer_name,
        order_date,
        product_name,
        quantity,
        unit_price,
        ( quantity * unit_price ) AS total
    FROM orders
    WHERE order_date >= ?
", [ dateAdd( "m", -1, now() ) ] );

CSVFile.fromQuery( qData )
    .delimiter( ',' )
    .quoteMode( "MINIMAL" )
    .save( "reports/monthly-orders.csv" );

From CSV to JSON

// Convert CSV to pretty-printed JSON
csv = CSV()
    .setHeaders( "Name", "Age", "City" )
    .addRow( [ "John", 30, "New York" ] )
    .addRow( [ "Jane", 25, "Los Angeles" ] );

jsonString = csv.toJson( true );
// Returns formatted JSON array of objects

From JSON to CSV

// Import JSON data and save as CSV
jsonData = '[
    { "Product": "Widget A", "Price": 10.99, "InStock": true },
    { "Product": "Widget B", "Price": 15.99, "InStock": false }
]';

CSVFile.fromJson( jsonData ).save( "products.csv" );

🎨 Flexible Configuration

The module supports virtually any CSV format you might encounter:

// Pipe-delimited with custom quote character
CSV()
    .delimiter( '|' )
    .quote( '\'' )
    .trim( true )
    .setHeaders( "Name", "Age", "City" )
    .addRow( [ "John O'Brien", 30, "New York" ] )
    .save( "data.txt" );

// Tab-separated values (TSV)
CSV()
    .delimiter( '\t' )
    .load( "data.tsv" );

// Handle comments and empty lines
CSV()
    .commentMarker( '#' )
    .ignoreEmptyLines( true )
    .load( "data-with-comments.csv" );

💼 Real-World Use Cases

Data Import Pipeline

// Build a robust data import system
CSV()
    .setPath( "imports/daily-feed.csv" )
    .delimiter( '|' )
    .trim( true )
    .ignoreEmptyLines( true )
    .filter( ( row ) => {
        // Validate required fields
        return row[ 1 ] != "" && row[ 2 ] != "" && row[ 3 ] > 0;
    } )
    .process( ( row ) => {
        // Insert validated rows into database
        try {
            queryExecute(
                "INSERT INTO products ( sku, name, price ) VALUES ( ?, ?, ? )",
                [ row[ 1 ], row[ 2 ], row[ 3 ] ]
            );
        } catch( any e ) {
            logError( "Failed to import row: " & row[ 1 ], e );
        }
    } );

Report Generation

// Generate monthly sales report
qSales = queryExecute( "
    SELECT
        DATE_FORMAT( order_date, '%Y-%m' ) as month,
        COUNT(*) as total_orders,
        SUM( order_total ) as revenue,
        AVG( order_total ) as avg_order
    FROM orders
    WHERE order_date >= DATE_SUB( NOW(), INTERVAL 12 MONTH )
    GROUP BY month
    ORDER BY month DESC
" );

CSVFile.fromQuery( qSales )
    .headerComments(
        "Monthly Sales Report",
        "Generated: " & now(),
        "Period: Last 12 Months"
    )
    .commentMarker( '#' )
    .quoteMode( "NON_NUMERIC" )
    .save( "reports/monthly-sales.csv" );

Data Consolidation

// Combine multiple CSV files from different sources
combined = CSV().setHeaders( "Name", "Email", "Source", "ImportDate" );

// Process each source file
sources = [
    { file: "mailchimp-export.csv", name: "MailChimp" },
    { file: "salesforce-export.csv", name: "Salesforce" },
    { file: "hubspot-export.csv", name: "HubSpot" }
];

sources.each( ( source ) => {
    CSV().process( source.file, ( row ) => {
        // Skip header rows
        if ( row[ 1 ] != "Name" && row[ 1 ] != "name" ) {
            combined.addRow( [
                row[ 1 ],
                row[ 2 ],
                source.name,
                now()
            ] );
        }
    } );
} );

combined.save( "combined-contacts.csv" );

📚 Complete Documentation

The bx-csv module is fully documented in our official BoxLang documentation, and we've even created a dedicated MCP Server for it:

🎁 Get Access

bx-ldap is available exclusively to BoxLang +/++ subscribers. Join our subscription program to access this and other premium modules that extend BoxLang's capabilities:

  • Priority Support - Get help when you need it
  • Premium Modules - Access subscriber-only modules
  • Early Access - Be first to try new features
  • Exclusive Benefits - CFCasts account, FORGEBOX Pro, and more

🛒 Purchase Options

Ready to unlock bx-ldap and other premium modules? Choose your plan:

🌟 View BoxLang Plans & Pricing

Need help choosing the right plan or have questions? Contact us directly:

📧 info@boxlang.io

Add Your Comment

Recent Entries

BoxLang 1.16.0 Released!

BoxLang 1.16.0 Released!

BoxLang 1.16.0 is here, closing 50 issues across new features, improvements, and bug fixes. The theme running through this release is control: control over how HTTP clients are created and reused, control over what happens when a request fails, control over how much data a response is allowed to buffer, control over when Java classpaths reload, and tighter alignment with CFML behavior in the edge cases that only show up in production.

Luis Majano
Luis Majano
August 04, 2026
Ortus & BoxLang July Recap 2026

Ortus & BoxLang July Recap 2026

July continued to showcase the rapid evolution of the Ortus ecosystem with major BoxLang releases, innovative developer tools, and expanded AI capabilities. From new runtime features and cloud-native integrations to practical learning resources and technical deep dives, this month's highlights reflect Ortus' commitment to building modern, high-performance solutions for the JVM.

The month also featured community initiatives, conference resources, and international events, including CFCa...

Victor Campos
Victor Campos
July 31, 2026