npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

invoicr

v1.6.1

Published

CLI tool to generate DOCX/PDF invoices from JSON configs with email integration

Readme

invoicr

A TypeScript CLI tool that generates DOCX and PDF invoices from JSON configuration files, with optional email integration for macOS.

Features

  • Generate professional invoices in DOCX and PDF formats
  • Multi-language support (German & English)
  • Flexible billing: hourly, daily, or fixed rates
  • Multiple currencies (EUR, USD)
  • Email drafts with PDF attachment (macOS Mail.app)
  • Separate email language from invoice language
  • Interactive client creation wizard
  • NEW in 1.6.0:
    • Bulk generation via CLI args: invoicr-bulk acme:40 other:10
  • In 1.5.0:
    • ESM modules (modern JavaScript module system)
    • Unit tests with Vitest (217 tests, 96% coverage)
  • In 1.4.0:
    • Custom invoice templates (default, minimal, detailed)
    • invoicr-export - Export invoice history to CSV/JSON
    • invoicr-bulk - Generate multiple invoices at once
  • In 1.3.0:
    • Multiple line items per invoice
    • Tax/VAT calculation with configurable rates
    • Logo support in invoice header
  • In 1.2.0:
    • invoicr-init - Interactive setup wizard for new workspaces
    • invoicr-list - List all available clients
    • --dry-run - Preview invoice without generating files
    • Due date calculation based on payment terms
    • Invoice history tracking (history.json per client)
    • Config validation with helpful error messages

Prerequisites

  • Node.js (v18+)
  • LibreOffice (for PDF conversion)
  • Mail.app (for email feature, macOS only)
# Install LibreOffice on macOS
brew install --cask libreoffice

Installation

From npm (global)

npm install -g invoicr

From source

git clone https://github.com/LeanerCloud/invoicr.git
cd invoicr
npm install
npm run build
cp provider.example.json provider.json  # Edit with your details

Usage

Generate Invoice

# If installed globally
invoicr <client-folder> <quantity> [options]

# If running from source
npm run invoice -- <client-folder> <quantity> [options]

Options

| Option | Description | |--------|-------------| | --month=MM-YYYY | Generate invoice for a specific month | | --email | Create email draft in Mail.app with PDF attached | | --test | Send email to provider instead of client (for testing) | | --dry-run | Preview invoice details without generating files |

Examples

# Generate invoice using example templates (no client setup needed)
invoicr acme-hourly 40        # 40 hours @ $150/hr
invoicr acme-daily 5          # 5 days @ €1,200/day
invoicr acme-fixed 15000      # Fixed $15,000

# Generate invoice for a past month
invoicr acme-hourly 80 --month=10-2025

# Generate invoice and create email draft
invoicr acme-daily 2 --email

# Test email (sends to your email instead of client)
invoicr acme-daily 2 --email --test

# Preview invoice without generating files
invoicr acme-hourly 40 --dry-run

# Use your own client (after creating with invoicr-new)
invoicr myclient 10

Initialize Workspace

Set up a new invoicing workspace with provider details:

invoicr-init

This interactive wizard will:

  1. Create provider.json with your business details
  2. Optionally create a sample client

List Clients

View all available clients in your workspace:

invoicr-list

Create New Client

# If installed globally
invoicr-new
invoicr-new --from=acme-hourly  # Use example template
invoicr-new --from=myclient     # Use existing client as template

# If running from source
npm run new-client
npm run new-client -- --from=acme-daily

Available Templates

| Template | Billing | Description | |----------|---------|-------------| | acme-hourly | Hourly | USD, English, 30-day payment terms | | acme-daily | Daily | EUR, German invoice + English email, translated descriptions | | acme-fixed | Fixed | USD, custom bank account, payment upon receipt | | acme-multiservice | Mixed | Multiple line items with tax (1.3.0+) | | acme-minimal | Hourly | Minimal template style (1.4.0+) | | acme-detailed | Daily | Detailed template style (1.4.0+) |

The command will prompt for:

  • Client folder name
  • Company name & address
  • Invoice/email language
  • Invoice prefix
  • Project reference (optional)
  • Service description, billing type, rate, currency
  • Payment terms
  • Bank details (optional)
  • Email recipients (To/CC)

Workspace Layout

your-workspace/
├── provider.json           # Your business details
├── clients/
│   └── <client>/
│       ├── <client>.json   # Client configuration
│       └── history.json    # Invoice history (auto-generated)
└── invoices/               # Generated invoices (DOCX/PDF)

Configuration

provider.json

Copy provider.example.json to provider.json and fill in your business details:

{
  "name": "Your Name",
  "address": {
    "street": "Street 123",
    "city": "12345 City, Country"
  },
  "phone": "+49 123 456789",
  "email": "[email protected]",
  "bank": {
    "name": "Bank Name",
    "iban": "DE00 0000 0000 0000 0000 00",
    "bic": "BICCODE"
  },
  "taxNumber": "12/345/67890",
  "vatId": "DE123456789"
}

Client JSON

Create a folder for each client with a JSON file inside (e.g., acme/acme.json). See examples/ for complete templates.

Hourly Billing (examples/acme-hourly.json)

{
  "name": "Acme Corp",
  "address": {
    "street": "123 Main Street",
    "city": "New York, NY 10001"
  },
  "language": "en",
  "invoicePrefix": "AC",
  "nextInvoiceNumber": 1,
  "projectReference": "Website Redesign",
  "service": {
    "description": "Frontend Development Services",
    "billingType": "hourly",
    "rate": 150,
    "currency": "USD"
  },
  "paymentTermsDays": 30,
  "email": {
    "to": ["Jane Smith <[email protected]>"],
    "cc": ["Accounting <[email protected]>"]
  }
}

Daily Billing with Translated Descriptions (examples/acme-daily.json)

{
  "name": "Acme GmbH",
  "address": {
    "street": "Musterstraße 42",
    "city": "10115 Berlin"
  },
  "language": "de",
  "emailLanguage": "en",
  "invoicePrefix": "ACM",
  "nextInvoiceNumber": 1,
  "projectReference": "Cloud Migration Project",
  "service": {
    "description": {
      "de": "Cloud-Infrastruktur & DevOps Beratung",
      "en": "Cloud Infrastructure & DevOps Consulting"
    },
    "billingType": "daily",
    "rate": 1200,
    "currency": "EUR"
  },
  "paymentTermsDays": 14,
  "email": {
    "to": ["Max Mustermann <[email protected]>"],
    "cc": ["Buchhaltung <[email protected]>"]
  }
}

Fixed Amount with Custom Bank (examples/acme-fixed.json)

{
  "name": "Acme Industries Ltd",
  "address": {
    "street": "100 Business Park Drive",
    "city": "London, EC1A 1BB"
  },
  "language": "en",
  "invoicePrefix": "AI",
  "nextInvoiceNumber": 1,
  "projectReference": "Mobile App Development - Phase 2",
  "service": {
    "description": "Software Development - Milestone Payment",
    "billingType": "fixed",
    "rate": 0,
    "currency": "USD"
  },
  "bank": {
    "name": "Revolut",
    "iban": "GB00 REVO 0000 0000 0000 00",
    "bic": "REVOGB21"
  },
  "paymentTermsDays": null,
  "email": {
    "to": ["John Doe <[email protected]>"]
  }
}

Notes:

  • emailLanguage: Use a different language for emails than the invoice
  • service.description: Can be a string or an object with de/en translations
  • bank: Optional. Overrides provider's bank details for this client
  • paymentTermsDays: Set to null for "payable upon receipt"

Configuration Options

| Field | Description | |-------|-------------| | language | Invoice language: "de" (German) or "en" (English) | | emailLanguage | Optional. Email language if different from invoice | | invoicePrefix | Prefix for invoice numbers (e.g., "AC" for AC-1, AC-2) | | billingType | "hourly", "daily", or "fixed" | | currency | "EUR" or "USD" | | rate | Rate per hour/day (ignored for fixed billing) | | bank | Optional. Overrides provider's bank details | | paymentTermsDays | Optional. If null, shows "payable upon receipt" | | projectReference | Optional. Shown in invoice details | | service.description | String or object with de/en translations | | email.to | Array of recipient email addresses | | email.cc | Optional. Array of CC email addresses | | lineItems | Optional. Array of line items (1.3.0+). Overrides single-service mode | | taxRate | Optional. Tax rate as decimal (e.g., 0.19 for 19%) (1.3.0+) | | template | Optional. Invoice template: "default", "minimal", or "detailed" (1.4.0+) |

Multiple Line Items (1.3.0+)

For invoices with multiple services, use the lineItems array instead of the CLI quantity:

{
  "name": "Multi-Service Client",
  "lineItems": [
    { "description": "Development", "quantity": 40, "rate": 150, "billingType": "hourly" },
    { "description": "Code Review", "quantity": 8, "rate": 175, "billingType": "hourly" },
    { "description": "Setup Fee", "quantity": 500, "rate": 1, "billingType": "fixed" }
  ],
  "taxRate": 0.19
}

When lineItems is present, the CLI quantity is ignored and all line items from the config are used.

Logo Support (1.3.0+)

Add a logo to your invoices by specifying logoPath in provider.json:

{
  "name": "Your Company",
  "logoPath": "logo.png"
}

Supported formats: PNG, JPG, GIF, BMP. The path can be absolute or relative to the current working directory.

Invoice Templates (1.4.0+)

Choose from three invoice styles by setting template in your client config:

| Template | Description | |----------|-------------| | default | Full-featured layout with all details (default) | | minimal | Clean, compact design with inline info | | detailed | Extended layout with emphasized payment info |

{
  "name": "My Client",
  "template": "minimal"
}

Export History (1.4.0+)

Export your invoice history to CSV or JSON:

invoicr-export                           # Export all to CSV (stdout)
invoicr-export --format=json             # Export all to JSON
invoicr-export --client=acme-hourly      # Export specific client
invoicr-export --output=invoices.csv     # Export to file

Bulk Generation (1.4.0+)

Generate multiple invoices at once using CLI arguments or a config file:

# CLI mode (1.6.0+)
invoicr-bulk acme:40 other:10
invoicr-bulk acme:40 other:10 --month=11-2025 --email
invoicr-bulk acme:40 other:10 --dry-run

# Config file mode
invoicr-bulk batch.json
invoicr-bulk batch.json --dry-run

Config file format:

{
  "invoices": [
    { "client": "acme-hourly", "quantity": 40 },
    { "client": "acme-daily", "quantity": 5, "month": "10-2025" },
    { "client": "acme-fixed", "quantity": 15000, "email": true }
  ]
}

Each invoice entry supports:

  • client (required): Client folder name
  • quantity (required): Quantity/amount for invoice
  • month (optional): Billing month (MM-YYYY format)
  • email (optional): Create email draft (true/false)

Email Feature

When using the --email flag, the tool creates a draft email in Mail.app with:

  • From: Provider's email address
  • To/CC: Pre-filled from client config (supports "Name " format)
  • Subject: Invoice number and month (e.g., "Invoice AC-1 (November 2025) - Your Name")
  • Body: Localized template with service description and amount
  • Attachment: PDF invoice

Email Languages

Set emailLanguage in the client config to use a different language for emails than the invoice. This is useful when:

  • Invoice must be in German (for accounting)
  • Client prefers English communication

Test Mode

Use --test to send the email to yourself (provider email) instead of the client:

invoicr acme-daily 2 --email --test

The subject will be prefixed with [TEST].

Output

Invoices are generated in the client's folder:

  • Rechnung_AC-1_November_2025.docx / .pdf (German)
  • Invoice_AC-1_November_2025.docx / .pdf (English)

The nextInvoiceNumber in the client JSON is automatically incremented after each invoice.

Development

# Run invoice without building (using tsx)
npm run dev -- acme-hourly 8

# Build TypeScript
npm run build

# Run tests
npm test

# Run tests in watch mode
npm run test:watch

Scripts

| Script | Description | |--------|-------------| | npm run build | Compile TypeScript to JavaScript | | npm run invoice | Generate an invoice | | npm run new-client | Create a new client interactively | | npm run init | Initialize a new workspace | | npm run list | List available clients | | npm run dev | Run invoice.ts directly with tsx | | npm test | Run unit tests with Vitest | | npm run test:watch | Run tests in watch mode |

License

MIT

Shameless Plug

This tool is brought to you by LeanerCloud. We help companies reduce their AWS costs using a mix of services and tools such as AutoSpotting.

Are you a freelancer with clients running workloads on AWS and notice cost optimization opportunities unrelated to your work? If you refer a client to us, we'll give you 50% of our first cost optimization invoice from that client.

Get in touch!