Learn-skills.dev invoice-generator
Generate professional invoices for freelancers and contractors. Creates a polished HTML invoice with live preview and download button, saved to /invoices. Stores contractor info (company name, address, phone) in a config file so it's only entered once. Asks for client name, email, line items, and optional payment terms each time. Auto-numbers invoices per client (saleshood_001, saleshood_002, etc.) and auto-dates to today. Supports multiple languages and currencies. The user can customize the HTML template to match their brand. Use this skill whenever the user mentions invoice, billing, bill a client, send an invoice, create an invoice, contractor invoice, freelance billing, or wants to generate any kind of invoice document — even if they just say something like 'I need to bill my client' or 'charge for last month's work'.
git clone https://github.com/NeverSight/learn-skills.dev
T=$(mktemp -d) && git clone --depth=1 https://github.com/NeverSight/learn-skills.dev "$T" && mkdir -p ~/.claude/skills && cp -r "$T/data/skills-md/aalvaaro/skills/invoice-generator" ~/.claude/skills/neversight-learn-skills-dev-invoice-generator && rm -rf "$T"
data/skills-md/aalvaaro/skills/invoice-generator/SKILL.mdInvoice Generator
Generate clean, professional invoices as self-contained HTML files with a live preview and a download-as-PDF button. Invoices are saved to a
/invoices folder in the current working directory.
How It Works
The skill uses two pieces:
- A config file (
in the project'sinvoice-generator.local.md
directory) that stores your company/contractor info so you don't have to re-enter it every time..claude/ - An HTML template (
bundled with this skill) that defines the look of the invoice. The user can swap this out or edit it to match their brand.assets/invoice-template.html
Each time the skill runs, it reads the config, asks for the per-invoice details (client, items, amounts), fills in the template, and writes the final HTML file. Invoice numbers are auto-generated per client.
Step 0: Read the Config
Look for a config file at
.claude/invoice-generator.local.md in the current project directory. This file uses YAML frontmatter to store the contractor's reusable info.
If the file exists, read it and extract the frontmatter fields. Confirm with the user: "I'll use your saved info — [Contractor Name], [Company Name]. Sound good?"
If the file doesn't exist, tell the user: "No config found yet — let me set up your info once so future invoices are instant."
Then collect each field using
AskUserQuestion, batching up to 4 questions per call. Run three calls sequentially:
Call 1 — locale & identity (4 questions):
— "What country are you based in?" (header: "Country"). Options: "Mexico" (description: "MX — America/Mexico_City timezone"), "United States" (description: "US — America/New_York timezone"), "Spain" (description: "ES — Europe/Madrid timezone").country
— "What language should invoices be written in?" (header: "Language"). Options: "Español" (description: "All labels in Spanish"), "English" (description: "All labels in English"), "Português" (description: "All labels in Portuguese").language
— "What's your company or business name?" (header: "Company"). Options: examples like "Acme LLC", "Smith Consulting" — the user will pick Other and type their own.company_name
— "What's your full name (as the contractor/sender)?" (header: "Name"). Options: examples like "Jane Smith", "John Doe".contractor_name
Call 2 — address & contact (4 questions):
— "What's your street address?" (header: "Address"). Options: examples like "123 Main St", "456 Oak Ave".street_address
— "City, State and ZIP code?" (header: "City/ZIP"). Options: examples like "Austin, TX 78701", "Morelia, 58000, Michoacan, Mexico".city_state_zip
— "What's your phone number?" (header: "Phone"). Options: examples like "+1 512-555-0100", "+52 443-555-0100".phone
— "What's your email address?" (header: "Email"). Options: examples like "you@company.com", "name@gmail.com".email
Call 3 — optional fields (2 questions):
— "Do you have a fax number?" (header: "Fax"). Options: "No fax" (description: "Skip this field"), "Yes, I have a fax number" (description: "I'll type it in").fax
— "Which currency do you use?" (header: "Currency"). Options: "$ MXN" (description: "Mexican Peso"), "$ USD" (description: "US Dollar"), "€ EUR" (description: "Euro"), "£ GBP" (description: "British Pound").default_currency
After collecting all answers, confirm the info back to the user in a summary and create the file:
--- company_name: "Acme Consulting LLC" contractor_name: "Jane Smith" street_address: "123 Main St" city_state_zip: "Austin, TX 78701" phone: "+1 512-555-0100" fax: "" email: "jane@acmeconsulting.com" default_currency: "$ MXN" country: "Mexico" language: "Español" --- # Invoice Generator Config This file stores your contractor/company info for invoice generation. Edit the YAML fields above to update your details.
Timezone from Country
Use the country to determine the timezone for date formatting:
- Mexico →
America/Mexico_City - United States →
(can be overridden)America/New_York - Spain →
Europe/Madrid - Other → ask or use system timezone
Language Labels
Based on the
language field, translate all template labels. Here's the mapping:
| Placeholder | English | Español | Português |
|---|---|---|---|
| INVOICE | FACTURA | FATURA |
| DATE | FECHA | DATA |
| FROM | DE | DE |
| BILL TO | FACTURAR A | COBRAR DE |
| QTY | CANT | QTD |
| Description | Descripción | Descrição |
| Unit Price | Precio Unitario | Preço Unitário |
| Total | Total | Total |
| SUBTOTAL | SUBTOTAL | SUBTOTAL |
| TOTAL DUE | TOTAL A PAGAR | TOTAL A PAGAR |
| PAYMENT DETAILS | DETALLES DE PAGO | DETALHES DE PAGAMENTO |
| NOTES | NOTAS | NOTAS |
| THANK YOU FOR YOUR BUSINESS! | ¡GRACIAS POR SU PREFERENCIA! | OBRIGADO PELA PREFERÊNCIA! |
| Download as PDF | Descargar como PDF | Baixar como PDF |
| en | es | pt |
Also format the invoice date according to the language:
- English:
March 27, 2026 - Español:
27 de marzo de 2026 - Português:
27 de março de 2026
Step 1: Gather Invoice Details
Collect invoice details using
AskUserQuestion. If the user already provided some info in their initial message (e.g., "invoice for Acme Corp, 10 hours at $150"), skip those fields and only ask about what's missing.
Call 1 — client info (3 questions):
- "Who is this invoice for? (client name)" (header: "Client"). Options: examples like "Acme Corp", "Smith Industries".
- "What's the client's address?" (header: "Address"). Options: examples like "123 Main St, City, ST 10001", "456 Oak Ave, Suite 200, City, ST 90210". If the user provides a multi-line address, split into street + city/state/zip lines.
- "What's the client's email address?" (header: "Email"). Options: examples like "client@company.com", "billing@acme.com".
Call 2 — line items & terms (3 questions):
- "What are the line items? List each with quantity, description, and unit price." (header: "Items"). Options: examples like "10 hrs × Consulting @ $150", "1 × Website Design @ $2,000" — the user will type their actual items via Other.
- "Any payment terms to include?" (header: "Terms"). Options: "Wire Transfer" (description: "Payment via wire / bank deposit"), "Due on receipt" (description: "Payment due immediately"), "Net 30" (description: "Payment due within 30 days"), "Custom terms" (description: "I'll specify my own terms or bank details").
- "Any notes to add?" (header: "Notes"). Options: "No notes" (description: "Skip this section"), "Add notes" (description: "I'll type my notes — e.g., project description, thank you message").
If the user gives partial info upfront, fill in what you can and only ask about what's missing — skip questions you already have answers for.
Auto-Numbering
The invoice number and date are not asked — they are generated automatically:
- Invoice date: Use today's date in the user's timezone (from config
), formatted according to thecountry
setting.language - Invoice number: Derived from the client name and a sequential counter:
- Slugify the client name: lowercase, replace spaces/special chars with hyphens (e.g., "SalesHood" →
, "Acme Corp" →saleshood
)acme-corp - List files in
matching the patterninvoices/
(e.g.,{slug}_NNN.html
,saleshood_001.html
)saleshood_002.html - If no files exist for this client, use
001 - Otherwise, take the highest number and add 1, zero-padded to 3 digits
- The invoice number displayed on the invoice is just the numeric part:
,001
, etc. (or whatever format the user prefers — if they have existing invoices with a different format like002
,100
, continue that sequence)101
- Slugify the client name: lowercase, replace spaces/special chars with hyphens (e.g., "SalesHood" →
Step 2: Build the Invoice
- Read the HTML template from
(bundled with this skill).assets/invoice-template.html - Replace all the placeholders with the actual data:
- Contractor/company info from the config
- Client info and line items from Step 1
- Calculate each line total (quantity × unit price)
- Calculate the subtotal and total due
- Fill in the auto-generated invoice number and date
- Fill in all language label placeholders from the table above
- The template has these placeholders — replace them all:
- Labels:
,{{l_invoice}}
,{{l_date}}
,{{l_from}}
,{{l_bill_to}}
,{{l_qty}}
,{{l_description}}
,{{l_unit_price}}
,{{l_total}}
,{{l_subtotal}}
,{{l_total_due}}
,{{l_payment_details}}
,{{l_notes}}
,{{l_thank_you}}
,{{l_download}}{{lang_code}} - Contractor:
,{{contractor_name}}
,{{street_address}}
,{{city_state_zip}}
,{{phone}}{{email}}
— if fax is provided, render as{{fax_line}}
; if not, replace with empty string<br>Fax: {{fax}}- Client:
,{{client_name}}{{client_email}}
— client's address lines (street, city/state/zip), each on its own line with{{client_address}}
. If no address provided, leave empty.<br>- Invoice:
,{{invoice_number}}{{invoice_date}}
— generate a{{line_items}}
for each item with<tr>
cells for qty, description, unit price, total<td>
,{{subtotal}}{{total_due}}
— if provided, render as:{{payment_terms_section}}
; if not, replace with empty string<div class="section"><h3>{{l_payment_details}}</h3><p>...</p></div>
— if notes provided, render as:{{notes_section}}
; if not, replace with empty string<div class="section"><h3>{{l_notes}}</h3><p>...</p></div>
— the currency symbol + code from config (e.g.,{{currency}}
)$49,000.00 MXN
- Labels:
Format all money amounts with two decimal places, the currency symbol, and the currency code.
Step 3: Save and Present
- Create the
directory in the current working directory if it doesn't exist./invoices - Save the invoice using the auto-numbering scheme:
invoices/{client_slug}_{NNN}.html- Example:
,invoices/saleshood_001.htmlinvoices/acme-corp_003.html
- Example:
- Tell the user where the file was saved and open it in the browser:
open invoices/{client_slug}_{NNN}.html
The HTML file is fully self-contained (inline CSS, no external dependencies) and includes:
- A print/download button that triggers the browser's print dialog (which allows saving as PDF)
- The button is hidden when printing so it doesn't appear in the PDF
Customizing the Template
If the user wants to change how invoices look, they can:
- Ask you to modify the template — e.g., "add my logo", "change the colors to blue", "add a notes section". Read the current template, make the changes, and save it back.
- Edit it directly — the template is at
within the skill directory. It's standard HTML/CSS withassets/invoice-template.html
markers.{{placeholder}}
When modifying the template, preserve all
{{placeholder}} markers or update the skill logic to match any changes.