Skip to content

Repository files navigation

CSV Storyteller

A free, open-source tool that processes CSV files, runs statistical analysis, and generates journalist-style narrative stories using AI.

MIT License Open Source Free Forever PRs Welcome


Overview

CSV Storyteller is an automated intelligence tool that transforms raw spreadsheets into readable, compelling narratives. Built for analysts, journalists, marketers, and founders, the application takes any uploaded CSV file, processes key statistical metrics directly in the browser, and hands those insights to an AI engine to draft a polished story.

The platform operates across three specific analysis modes: Marketing, Startup, and Finance. Each mode applies a different analytical lens and tonal perspective to the data, ensuring the resulting narrative matches the context of the domain.

Every generated output strictly follows a professional journalistic structure: a catchy headline, a summarizing lede, a detailed body story thoroughly grounded in the data, and a memorable kicker.


Features

Analysis Engine

  • Automatic numeric column detection
  • Statistical computation: mean, median, min, max, std deviation, trend
  • Anomaly detection via z-score (flags > 2.0)
  • Peak and largest-drop identification
  • Data strength classification (strong / moderate / weak)

AI Narrative

  • Mode-specific journalistic prompting (Marketing / Startup / Finance)
  • Anti-hallucination constraints (every claim must cite a data point)
  • No-speculation enforcement
  • Graceful fallback for low-signal data

Product

  • No account required
  • Raw CSV never stored — only computed summary stats sent to backend
  • Copy to clipboard + download as .txt
  • MIT Licensed — self-hostable

Demo

CSV Storyteller App Interface CSV Storyteller About Page CSV Storyteller Pricing Page


Tech Stack

Layer Technology Purpose
Frontend HTML, CSS, Vanilla JavaScript Zero-build, fast-loading client interface
CSV Parsing PapaParse Secure, browser-side data extraction
Backend Node.js, Express.js API routing, AI orchestration, and security layer
AI Google Gemini API Natural language narrative generation
Database Turso (libSQL) Edge database storing generated stories and metadata
Security Helmet.js, express-rate-limit HTTP header protection and endpoint throttling
Validation Zod Strict schema requirements for incoming JSON payloads

Project Structure

csv-storyteller/
├── frontend/
│   ├── index.html           # Main application interface and form
│   ├── about.html           # Project background and methodology
│   ├── pricing.html         # Free software declaration page
│   ├── styles.css           # Global stylesheet and CSS variables
│   └── script.js            # Client-side validation, rendering, and fetch logic
├── src/
│   ├── server.js            # Express application entry point
│   ├── config.js            # Environment variable validation and export
│   ├── routes/
│   │   └── analyze.js       # Core HTTP endpoint logic for story generation
│   ├── analysis/
│   │   ├── index.js         # Central exporter for analysis algorithms
│   │   ├── marketing.js     # Marketing metrics analyzer
│   │   ├── startup.js       # Startup metrics analyzer
│   │   └── finance.js       # Finance metrics analyzer
│   ├── prompts/
│   │   └── index.js         # Mode-specific AI instructions and constraints
│   ├── db/
│   │   ├── index.js         # Turso database connection handler
│   │   └── migrations.js    # Schema creation and sync logic
│   ├── middleware/
│   │   ├── rateLimiter.js   # Global and endpoint-specific memory limiters
│   │   ├── validate.js      # Zod schema interceptor and payload evaluator
│   │   └── errorHandler.js  # Dedicated error masking and HTTP response mapping
│   └── utils/
│       ├── stats.js         # Reusable mathematical calculation algorithms
│       └── logger.js        # Environment-aware, sanitized console logging
├── .env.example             # Template for required environment variables
├── .gitignore               # Excluded paths and secret files
├── package.json             # Backend dependencies and run scripts
└── README.md                # Project documentation and guide

Getting Started

Prerequisites

Installation

  1. Clone the repository
git clone https://github.com/cold-cofffeee/CSV-Storyteller.git
  1. Install backend dependencies
cd CSV-Storyteller
npm install
  1. Configure environment variables
cp .env.example .env
  1. Populate your variables inside .env:

    • GEMINI_API_KEY (Your Google AI authentication token)
    • TURSO_DATABASE_URL (Your Turso instance URL)
    • TURSO_AUTH_TOKEN (Your Turso access token)
    • PORT (Defaults to 3000)
    • ALLOWED_ORIGIN (Defaults to http://localhost:5500 for local development)
    • NODE_ENV (Defaults to development)
  2. Run the database migration to create the stories table

npm run migrate
  1. Start the backend server
npm run dev
  1. Serve the frontend application Use the VSCode "Live Server" extension on the frontend/ folder, or run:
npx serve frontend

The app will be running at http://localhost:5500 (frontend) and http://localhost:3000 (backend).


Environment Variables

Variable Required Description
GEMINI_API_KEY Yes Token for Google's Gemini models
TURSO_DATABASE_URL Yes Endpoint format: libsql://your-db-name.turso.io
TURSO_AUTH_TOKEN Yes Valid access token generated for your Turso DB
PORT No Server listen port. Defaults to 3000
ALLOWED_ORIGIN Yes Exact domain allowed for CORS requests (e.g., frontend host)
NODE_ENV Yes development or production to control logging/stacktraces

Note: Never commit your .env file. It is already in .gitignore.


Deployment

Frontend (Netlify)

  1. Navigate to netlify.com/drop.
  2. Drag and drop your /frontend directory directly into the browser.
  3. Set the backend URL in script.js before deploying, or use a _redirects proxy file to route traffic seamlessly.

Backend (Render.com)

  1. Connect your GitHub repository to Render as a Web Service.
  2. Build command: npm install
  3. Start command: node src/server.js
  4. Use the Render dashboard to input your environment variables (Gemini Key, Turso URLs, etc.).
  5. Copy the backend service URL safely generated by Render, and paste it securely into your Netlify frontend.

Tip: Set NODE_ENV=production in Render's environment variables. This disables stack traces in error responses.

Never expose .env files in production environments; always provision sensitive keys securely via your host's dedicated environment variables manager dashboard.


API Reference

POST /api/analyze

Method: POST
Headers:
Content-Type: application/json

Request Body:

{
  "mode": "marketing",
  "data": [
    { "month": "Jan", "sales": 400 },
    { "month": "Feb", "sales": 600 }
  ],
  "headers": ["month", "sales"],
  "rowCount": 2
}

Success Response (200 OK):

{
  "headline": "A Surprising Shift in Q1 Momentum",
  "lede": "Early signals indicate unexpected sales behavior emerging from the data.",
  "story": "The dataset reflects robust progression across key indicators...",
  "kicker": "Only time will tell if this trajectory holds true."
}

Error Responses:

Status Error Code Meaning
400 Bad Request The JSON payload failed Zod schema validation (e.g., missing headers).
422 Unprocessable Entity The payload structure was correct, but business logic blocked it (e.g., too many rows).
429 Too Many Requests The global or route-specific rate limits were exceeded.
500 Internal Server Error Gemini generation failed, DB operations failed, or an unknown exception occurred.

Contributing

We are constantly looking to expand the analytics engine and welcome contributions from everyone!

How to contribute:

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/your-feature-name
  3. Commit your changes: git commit -m 'Add: your feature description'
  4. Push to the branch: git push origin feature/your-feature-name
  5. Open a Pull Request

What we'd love help with:

  • New analysis modes (e.g., HR, E-commerce, Healthcare)
  • Additional language support
  • A richer stats engine (seasonality detection, correlation)
  • UI improvements and accessibility
  • Test coverage

For major changes, please open an issue first to discuss what you'd like to change.


License

This project is licensed under the MIT License. See the LICENSE file for details.


Built and maintained by @cold-cofffeee
If you find this useful, consider starring the repo ★


CSV Storyteller — Free, forever. MIT Licensed.

About

CSV Storyteller is a free, open-source tool that reads your spreadsheet data and generates a journalist-style narrative — complete with a headline, a lede, context, anomalies, and a kicker. No data science degree required.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages