/ build-guides / How to Build an Invoice Tool as a Solo Developer
build-guides 11 min read

How to Build an Invoice Tool as a Solo Developer

Complete guide to building an invoice tool as a solo developer - tech stack, architecture, timeline, and tips.

Hero image for How to Build an Invoice Tool as a Solo Developer

What You're Building

An invoice tool lets freelancers and small businesses create, send, and track invoices. It sounds boring, and that's exactly why it's a great business. Every freelancer, consultant, and small business owner needs to send invoices, and a surprising number of them are still using Word documents or Google Docs templates. The pain is real and recurring.

I send invoices regularly and I've used everything from FreshBooks to literally just emailing a PDF I made in Google Docs. The tools that won me over were always the simplest ones. Create invoice, send it, get paid, track it. No bloat. No 47-tab dashboard. Just invoicing that works.

Difficulty & Timeline

Aspect Detail
Difficulty Medium
Time to MVP 4-6 weeks
Ongoing Maintenance Low to Medium
Monetization Freemium ($9-29/month), per-invoice pricing

Next.js or SvelteKit for the dashboard, with a Node.js or Django backend. For PDF generation, use a library like Puppeteer (render HTML to PDF) or a service like Gotenberg. Don't try to build PDF generation from scratch with low-level libraries. HTML-to-PDF gives you beautiful, customizable invoices with minimal effort.

PostgreSQL for storing clients, invoices, line items, and payment status. Stripe for accepting payments on behalf of your users (Stripe Connect if users want to accept card payments through your platform) or simply integrate with payment tracking where users manually mark invoices as paid.

Current Versions to Pin (checked May 2026)

These are the latest published releases at the time of writing. Pin exact versions in your lockfile so a stray npm update does not surprise you mid build.

Tool Latest version Install / docs
Next.js 16.2.6 npm install next@16.2.6 react react-dom
Svelte / SvelteKit 5.56.0 / 2.61.1 npm create svelte@latest
Node.js (LTS) 24.16.0 "Krypton" use the active LTS, not Current (26.2.0)
Django 6.0.5 pip install "Django==6.0.5"
PostgreSQL 18.4 latest stable major line is 18
Puppeteer 25.1.0 npm install puppeteer@25.1.0
Gotenberg 8.33.0 docker pull gotenberg/gotenberg:8.33.0
Stripe (Node SDK) 22.2.0 npm install stripe@22.2.0
Resend (Node SDK) 6.12.4 npm install resend@6.12.4
SendGrid (Node SDK) 8.1.6 npm install @sendgrid/mail@8.1.6

For context on how battle tested these are, the npm weekly download counts at the time of writing are roughly 40.1M for next, 10.1M for puppeteer, 6.7M for resend, 3.6M for @sendgrid/mail, and 4.8M for svelte. On GitHub, Next.js sits around 139.6k stars, Svelte 86.7k, Puppeteer 94.4k, and Gotenberg 12.3k. None of these are risky bets.

What the PDF and Email Choices Actually Cost

If you go with Puppeteer for PDF generation, the library itself is free and open source, but it bundles a headless Chromium and is memory hungry, so plan for a worker process rather than rendering inside a request handler. Gotenberg is the alternative if you would rather run PDF rendering as a separate Docker service, which keeps Chromium out of your app process entirely.

For email delivery, Resend's free tier covers 3,000 emails per month capped at 100 emails per day, and its paid Pro plan starts at $20 per month for 50,000 emails, rising to $35 per month for 100,000 (check current pricing before you commit). SendGrid's permanent free tier is 100 emails per day; its Essentials plan starts around $19.95 per month for 100,000 emails, and Pro starts at $89.95 per month for 100,000 emails with a dedicated IP. For a solo invoicing tool, either free tier comfortably covers your early users.

For payments, Stripe charges 2.9% plus 30 cents per successful US card transaction on standard online pricing, with additional fees for manually entered cards (plus 0.5%), international cards (plus 1.5%), and currency conversion (plus 1%). Stripe Connect lets you set your own platform pricing on top, with a starting platform fee referenced at 0.25% (verify current Connect pricing for your model). Budget those processing fees into your own margins before you settle on a $9 to $19 monthly plan.

Step-by-Step Plan

Phase 1: Core Invoicing (Week 1-3)

Build the invoice creator. Users add their business details, client information, line items (description, quantity, rate), tax rates, and notes. Calculate totals automatically. Show a real-time preview of the invoice as they build it.

Add PDF generation. When the invoice is ready, generate a clean, professional PDF. Use an HTML template styled with CSS, render it with Puppeteer or a similar tool. This approach lets you create beautiful invoices without fighting PDF libraries.

Build the client management system. Users add clients once and reuse them across invoices. Store client name, email, address, and any default payment terms.

Phase 2: Sending & Tracking (Week 3-5)

Add email delivery. Users click "Send" and the invoice gets emailed to the client as a PDF attachment (plus an optional web link to view and pay online). Use Resend or SendGrid for reliable email delivery.

Build the dashboard showing all invoices with their status: draft, sent, viewed, paid, overdue. Automatic overdue detection based on due dates. Optional reminder emails for overdue invoices since this is a feature freelancers love because nobody enjoys chasing payments manually.

Add a public invoice page where clients can view the invoice in their browser and optionally pay online. This web view should be clean, professional, and mobile-friendly.

Phase 3: Payments & Polish (Week 5-6)

Integrate online payments. Let your users accept credit card or bank transfer payments directly through the invoice. Stripe Connect is the cleanest option here. When a client pays, the invoice automatically updates to "Paid" status.

Add recurring invoices for users with subscription clients. Monthly retainers are common for freelancers and consultants. Set it once, invoices go out automatically.

Build a simple reporting dashboard. Total invoiced, total paid, total outstanding, revenue by month. Freelancers need this data for tax time and it takes maybe a day to build.

Key Features to Build First

Invoice creator with live preview. Line items, tax calculation, customizable templates. The preview should look exactly like the final PDF.

PDF generation. Clean, professional PDFs that users aren't embarrassed to send. Use HTML-to-PDF for easy customization.

Email delivery. One-click send with the PDF attached. Track when the client opens the email if possible.

Status tracking. Draft, sent, viewed, paid, overdue. Automatic overdue detection with optional reminders.

Client management. Store client details for reuse. Saves time on every subsequent invoice.

Architecture Overview

Dashboard (Next.js / SvelteKit)
  └── API (Node.js / Django)
        ├── Invoice CRUD (with line items)
        ├── Client management
        ├── PDF generation (Puppeteer / Gotenberg)
        ├── Email delivery (Resend / SendGrid)
        ├── Payment processing (Stripe Connect)
        ├── Recurring invoice scheduler
        └── Billing (your plans via Stripe)

Storage
  ├── PostgreSQL (invoices, clients, users)
  ├── S3/R2 (generated PDFs, logos)
  └── Redis (job queue for emails, reminders)

Common Pitfalls

Making ugly PDFs. The invoice PDF is your product's first impression. If it looks like a spreadsheet dump, nobody will take it seriously. Invest time in a clean, professional template. Look at what FreshBooks and Wave invoices look like and match that quality.

Ignoring tax complexity. Different countries have different tax requirements. VAT, GST, sales tax, reverse charge. You don't need to support all of them at launch, but design your data model to accommodate multiple tax rates and tax types. At minimum, support a configurable tax percentage per invoice.

Building an accounting system. You're building an invoicing tool, not QuickBooks. Don't add expense tracking, bank reconciliation, or double-entry bookkeeping. Stay focused on creating, sending, and tracking invoices. Users who need full accounting will connect your tool to their existing accounting software.

Overcomplicating templates. Start with one beautiful, professional template. You can add more later. I've seen invoice tools launch with 20 mediocre templates instead of 3 excellent ones. Quality over quantity.

Not handling currencies properly. Freelancers work internationally. Support multiple currencies from day one. Store amounts in the invoice's currency, not your default currency. Display the currency symbol correctly. This is easy to design for upfront and painful to retrofit.

Common Errors and Fixes

These are the failure modes that bite people building this exact stack. Each one maps to a real behavior in the current versions above.

Puppeteer launches but Chromium is missing. On Puppeteer 25, the browser binary download is controlled by environment and config, and in slim Docker images or some CI setups the Chromium download gets skipped. If page.pdf() fails with a browser-not-found error, install the browser explicitly with npx puppeteer browsers install chrome and confirm the launch path. In Alpine-based containers you also need the system fonts and shared libraries Chromium expects, otherwise the PDF renders blank or with boxes instead of glyphs.

PDFs render before the page is ready. Calling page.pdf() too early produces invoices missing fonts, logos, or computed totals. Wait for the network and webfonts to settle (navigate with waitUntil: 'networkidle0' and await document.fonts.ready) before generating. Set printBackground: true or your CSS background colors and table shading silently drop out of the PDF.

Stripe webhook signature verification fails. The most common cause is that the request body was parsed as JSON before verification. Stripe signature checks need the raw, unparsed request body. In Next.js route handlers read the raw body, and pass your whsec_... signing secret to stripe.webhooks.constructEvent. A 400 on the webhook endpoint almost always means the body was already transformed or the wrong secret was used.

Stripe Connect payouts go to the wrong account. When charging on behalf of a connected account, you must set the connected account context (the Stripe-Account header or stripeAccount option), otherwise the charge lands on your platform account instead of your user's. Test this in test mode with a real connected test account before launch.

Resend or SendGrid mail silently does not arrive. Both providers require a verified sending domain (SPF and DKIM records) before mail reliably lands. On the Resend free tier you are also capped at 100 emails per day, so a batch of overdue reminders can hit the daily limit and the rest queue or fail. SendGrid's free tier is likewise 100 per day. If delivery looks fine in the dashboard but nothing arrives, check domain authentication first, then the daily cap.

PostgreSQL stores the wrong amount. Never store money as a float. Use numeric (or integer minor units, for example cents) so 0.1 plus 0.2 does not drift. This is the single most common data-model bug in invoicing tools and it is painful to fix once real invoices exist.

Next.js 16 build breaks on an old config. Next.js 16 removed and changed several APIs from earlier majors. If you scaffolded against an older tutorial, expect to update route handler signatures and any deprecated config keys. Read the upgrade notes in the official docs rather than guessing.

Timeline Estimate

Phase Time What You're Doing
Invoice creator + PDF 3 weeks Builder, preview, PDF generation, clients
Sending + tracking 2 weeks Email delivery, status tracking, reminders
Payments + polish 1-2 weeks Stripe Connect, recurring invoices, reporting
Total 4-6 weeks Ready for freelancers to send invoices

Is This Worth Building?

Absolutely. Invoicing is one of those evergreen businesses that will always have demand. Every freelancer, consultant, and small business needs it. The competition (FreshBooks, Wave, Zoho Invoice) is established but often bloated and expensive. There's real space for a simpler, cheaper alternative that nails the core workflow.

The freemium model works great here. Let users send 5 invoices/month for free, charge $9-19/month for unlimited invoices, custom branding, and recurring invoices. A $19/month price point is easy for any freelancer to justify when they're invoicing thousands per month. 500 paying users at $15/month is $90k/year. And invoicing tools have very low churn because switching means migrating client data and invoice history.

Sources

All versions, pricing, download counts, and star counts above were fetched from these sources (checked-on 2026-05-30). Pricing and limits change, so verify current numbers before you build a business model on them.

Built by Kevin

Like this? You'll like what I'm building too.

Two ways to support and get more of this work.

Desktop App

HEARTH

A privacy-first Life OS for your desktop. Journal, tasks, and notes that stay on your machine. Coming soon, direct download from this site.

Read more
Digital Products

MY TOOLKITS

Receipts-first toolkits for shipping after hours, building Claude agents, publishing on Amazon, and more. The exact methods I used, not theory.

Browse on Whop

Need This Built?

Kevin builds products solo, from first version to live. If you want something like this made, work with him.