/ tech-stacks / Best Tech Stack for an Invoice / Billing Tool as a Solo Developer
tech-stacks 7 min read

Best Tech Stack for an Invoice / Billing Tool as a Solo Developer

The best tech stack for building an invoice / billing tool as a solo developer - frameworks, databases, hosting, and tools.

Best Tech Stack for an Invoice / Billing Tool as a Solo Developer

Invoicing is a problem every freelancer, contractor, and small business faces. FreshBooks, Wave, and Invoice Ninja have proven the market, but there's still room for focused, niche invoicing tools: invoicing for specific industries, subscription billing management, or stripped-down tools for freelancers who find QuickBooks overwhelming. The technical challenge is building clean document generation, payment integration, and financial reporting without the bloat.

Here's the stack that lets you build a professional invoicing tool solo.

Layer Pick
Frontend Next.js (React)
Backend Next.js API routes + tRPC
Database PostgreSQL (via Prisma)
PDF Generation React-PDF (@react-pdf/renderer)
Payments Stripe
Email Resend
Hosting Vercel
File Storage Cloudflare R2

Frontend: Next.js

An invoicing tool is a classic CRUD application with a few twists: invoice creation with a visual preview, client management, reporting dashboards, and a public payment page for clients.

Next.js handles all of these:

  • Dashboard - Overview of outstanding invoices, revenue charts, recent activity
  • Invoice editor - Line items, taxes, discounts, notes, branding
  • Client portal - Public pages where clients view and pay invoices
  • Reports - Revenue over time, outstanding amounts, payment aging

For the invoice editor, build a form-based UI rather than a visual drag-and-drop builder. Invoices have a standard structure: header (logo, company info), client details, line items table, subtotals/taxes/discounts, and footer notes. A well-designed form that shows a live preview alongside it is faster to use than a free-form editor.

The live preview should render identically to the final PDF. Use the same component for both the on-screen preview and PDF generation.

Backend: Next.js API Routes + tRPC

Your backend handles standard CRUD operations plus some invoicing-specific logic:

  • Invoice numbering - Auto-generate sequential invoice numbers (INV-001, INV-002)
  • Tax calculations - Apply tax rates correctly with rounding
  • Recurring invoices - Generate and send invoices on a schedule
  • Payment processing - Accept payments via Stripe payment links
  • Overdue tracking - Flag overdue invoices and trigger reminder emails
  • Multi-currency - Store amounts in the invoice currency with exchange rates

tRPC keeps your frontend and backend type-safe. Invoice line item calculations (quantity x rate, subtotals, tax, discounts) need to be precise. Shared TypeScript types between frontend and backend prevent mismatches.

Important: Store all monetary values as integers (cents), not floats. $149.99 becomes 14999. This prevents floating-point rounding errors that cause invoice totals to be off by a cent.

Database: PostgreSQL + Prisma

Invoicing data is highly relational: clients have invoices, invoices have line items, invoices have payments, payments link to transactions. PostgreSQL handles this naturally.

Core schema:

  • users - Business owner accounts with company details
  • clients - Client contact info, billing address, default currency
  • invoices - Invoice number, client, status (draft/sent/paid/overdue), due_date, totals
  • line_items - Description, quantity, unit_price, tax_rate, amount
  • payments - Amount, method, transaction_id, paid_at
  • recurring_schedules - Frequency, next_send_date, template_invoice

Prisma provides clean migrations and type-safe queries. Host on Neon (free tier) or Supabase.

One schema tip: store calculated totals (subtotal, tax_total, discount_total, grand_total) on the invoice record itself, not just on line items. This makes reporting queries fast and ensures the total shown to the client never changes after the invoice is sent, even if you later change tax rates in your settings.

PDF Generation: React-PDF

Generating professional-looking invoices as PDFs is a core feature. @react-pdf/renderer lets you define PDF layouts using React components. Same mental model as building UI, but the output is a PDF.

This is the right approach for several reasons:

  1. You can share styles and components between the web preview and PDF
  2. React-PDF runs on the server (generate PDFs in API routes)
  3. It supports custom fonts, logos, colors, and complex layouts
  4. No external PDF API service needed (no per-document costs)

Generate PDFs on-demand when a user downloads an invoice or when you need to email one. Store the generated PDF in Cloudflare R2 for quick re-downloads.

For the client-facing payment page, render the invoice as HTML (not PDF) so clients can view it on any device without downloading a file. Include a "Download PDF" button for their records.

Payments: Stripe

Stripe handles the payment collection from clients. When a user sends an invoice, include a payment link that opens a Stripe Checkout session for the invoice amount.

The flow:

  1. Business owner creates and sends invoice
  2. Email contains a link to the invoice payment page
  3. Client clicks "Pay Invoice" on the page
  4. Stripe Checkout opens with the invoice amount
  5. Client pays with card, Apple Pay, bank transfer, etc.
  6. Webhook fires, your app marks the invoice as paid
  7. Both parties get confirmation emails

Use Stripe Connect if you want to process payments on behalf of your users (your platform facilitates the payment). This lets you take a small platform fee per transaction, which is an additional revenue stream beyond subscriptions.

Email: Resend

Invoicing is an email-heavy product. You'll send:

  • Invoice delivery (with PDF attached or payment link)
  • Payment confirmations
  • Overdue reminders (automated sequences: 1 day, 7 days, 14 days past due)
  • Recurring invoice notifications

Resend with React Email templates gives you beautiful, consistent transactional emails. Build your email templates with React components (same pattern as the rest of your app) and send via Resend's API.

The automated reminder sequence is a key feature. Set up a cron job (Vercel Cron or a simple setInterval on a Railway worker) that checks for overdue invoices daily and sends escalating reminders.

Nice-to-Haves

  • Multi-currency support with exchange rate API (exchangerate.host, free)
  • Stripe for your own SaaS billing (separate from invoice payments)
  • Time tracking integration - Log hours and generate invoices from tracked time
  • Expense tracking - Attach receipts and track business expenses
  • Financial reports - Profit/loss, accounts receivable aging, revenue by client
  • Zapier/Make webhooks for integrations with accounting software

Monthly Cost Breakdown

Service Cost
Vercel (Pro) $20/month
Neon Postgres (free tier) $0
Cloudflare R2 (PDFs) ~$1/month
Resend (free tier, 3k emails/mo) $0
Stripe 2.9% + 30c per payment processed
Domain $1/month
Total ~$22/month + Stripe fees

Stripe fees are paid by your users' clients (or absorbed by your users), not by you. Your SaaS costs are just the dashboard hosting and database.

Conclusion

The best stack for a solo developer building an invoice tool: Next.js with tRPC for the full-stack application, PostgreSQL with Prisma for financial data, React-PDF for document generation, Stripe for payment collection, Resend for email delivery, and Vercel for hosting.

The key to a successful invoicing tool is simplicity. Freelancers and small businesses choose tools like Wave and Invoice Ninja because QuickBooks is too complex. Focus on the core loop: create invoice, send to client, get paid, track the payment. Make that loop as fast and frictionless as possible. Every feature you add beyond that should make the core loop easier, not add complexity. Resist the urge to build a full accounting suite.