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 Is Heading to JavaLand 2026! 🚀

BoxLang Is Heading to JavaLand 2026! 🚀

We’re excited to announce that the team behind BoxLang will be attending JavaLand 2026 as Startup Sponsors!

From March 10–12, 2026, the Java community will gather at Europa-Park for one of the most unique and immersive developer conferences in Europe. With nearly 130 presentations across multiple tracks, workshops, and community activities, JavaLand brings together developers, architects, and technology leaders from across the JVM ecosystem.

For the BoxLang team, this is a fantastic opportunity to connect with the Java community and continue our mission: modernizing software development on the JVM while empowering developers with productive, flexible tools.

Maria Jose Herrera
Maria Jose Herrera
March 06, 2026
The CFML Talent Gap Is Real: Scale Your ColdFusion Team Without Hiring Full-Time

The CFML Talent Gap Is Real: Scale Your ColdFusion Team Without Hiring Full-Time

ColdFusion applications still power critical systems across industries.

From universities and healthcare platforms to financial services and enterprise internal tools, CFML continues to run many systems organizations depend on every day.

But there’s a growing challenge many teams are quietly facing:

Finding experienced CFML developers is getting harder.

And when internal teams are already stretched thin, even small projects or performance issues can quickly turn ...

Cristobal Escobar
Cristobal Escobar
March 06, 2026
Discover the tools, tricks, and techniques every modern CFML and BoxLang developer needs!

Discover the tools, tricks, and techniques every modern CFML and BoxLang developer needs!

Into the Box 2026 is officially on the horizon, and it’s shaping up to be our most impactful conference yet.

Our mission this year is simple: **Make modernization approachable for everyone.** Whether you’re a seasoned ColdFusion veteran or a developer just starting your BoxLang journey, we’ve priced this event to ensure the entire community can join us in person.

Victor Campos
Victor Campos
March 05, 2026