Building EliteInvoice
A Simple Invoicing Application for Freelancers and Small Businesses
The Problem: Invoicing Tools Are Either Too Complex or Too Expensive
As a freelancer or small business owner, you need to send invoices and get paid. But existing solutions force painful trade-offs:
- QuickBooks and FreshBooks are feature-bloated—you pay for 100 features but only need 5
- Wave is free but shuts down features and changes pricing unpredictably
- Stripe Invoicing charges per invoice—costs add up quickly at scale
- Excel spreadsheets work but look unprofessional and lack automation
- Most tools require creating accounts with passwords you'll forget
I wanted something different: professional invoicing with zero friction. Log in with your email, create invoices, track payments, done.
The result: EliteInvoice—a clean, focused invoicing tool that does one thing extremely well.
The Vision: Invoicing Without the Bloat
I built EliteInvoice with a clear philosophy: do the essential things perfectly, skip everything else. The core principles:
Passwordless Authentication
Magic link login means no passwords to remember. Enter email, click link, you're in. Secure and frictionless.
Client Management
Organize clients with contact info, view invoice history per client, archive inactive clients to keep things clean.
Financial Dashboard
See your business at a glance—monthly/yearly income, outstanding invoices, payment trends with beautiful Chart.js visualizations.
AI-Powered Creation
Describe your work in plain English, let AI generate professional invoice line items. Stop wrestling with itemization.
The Tech Stack: Production-Ready from Day One
Next.js 14 with App Router
The App Router provides React Server Components for fast initial loads and seamless client-side navigation. API routes handle all backend logic—authentication, invoice CRUD, PDF generation—in a single deployable unit. No separate backend server to manage.
Prisma ORM + PostgreSQL
Type-safe database access with Prisma prevents runtime errors. The schema defines Users, Clients, Invoices, Items, and Bills with proper relations. PostgreSQL handles complex queries for financial reporting and provides ACID transactions for payment recording.
Magic Link Authentication
Custom JWT-based magic link system. Users enter email, receive a secure link via Nodemailer, click to authenticate. Tokens are time-limited and single-use. No passwords means no password resets, no credential stuffing attacks, no forgotten password support tickets.
Stripe for Subscriptions
Subscription management with Stripe handles plan tiers (Free, Pro, Lifetime). Webhooks process subscription lifecycle events. Usage-based limits (invoices per month) enforced at the API layer. AppSumo lifetime deal codes integrated for launch promotion.
jsPDF for Invoice Generation
Client-side PDF generation with jsPDF and jspdf-autotable creates professional invoices instantly. No server round-trip needed—PDFs render in the browser with business branding, line items, totals, and payment instructions.
Anthropic Claude for AI Features
The AI-powered invoice creation uses Claude to parse natural language descriptions into structured invoice items. Describe "10 hours of React development at $150/hour plus hosting setup" and get properly formatted line items automatically.
The Architecture: Simplicity That Scales
EliteInvoice follows a straightforward architecture optimized for solo developer productivity:
Database Schema Design
The Prisma schema defines the core entities:
- User: Account with business info (name, address, logo), subscription status, QuickBooks integration tokens
- Client: Customer entity with name, email, phone, address, archive status
- Invoice: Core entity with number, amount, due date, status (DRAFT, PENDING, PAID, OVERDUE)
- Item: Line items on invoices with name, quantity, price
- InvoiceEvent: Audit trail of status changes and actions
- Bill: Internal bill tracking with Wise payment integration
- Plan: Subscription tiers with Stripe product/price IDs
Component Architecture
React components are organized by feature with clear separation of concerns:
- InvoiceForm: Create/edit invoices with dynamic line items, client selection, due date picker
- InvoiceTable: Sortable, filterable list with status badges and quick actions
- ClientForm/ClientTable: CRUD operations for client management
- DashboardCard: Reusable stat cards for the financial overview
- QuickInvoiceCreator: AI-powered natural language invoice generation
- InvoiceTimeline: Visual history of invoice events and status changes
All UI components use shadcn/ui primitives (Dialog, Select, Toast) for accessibility and consistent styling.
Magic Link Authentication: Passwords Are So 2010
Traditional password authentication creates friction and security risks. Magic links solve both:
The Authentication Flow
- User enters email on login page
- Server generates JWT with email, expiration (15 minutes), and random nonce
- Nodemailer sends email with magic link containing the token
- User clicks link → server verifies JWT signature and expiration
- If valid, create session cookie and redirect to dashboard
- If user doesn't exist, auto-create account (zero-friction onboarding)
// Generate magic link token
const token = jwt.sign(
{ email, nonce: crypto.randomBytes(32).toString('hex') },
process.env.JWT_SECRET,
{ expiresIn: '15m' }
);
// Send via Nodemailer
await transporter.sendMail({
to: email,
subject: 'Your EliteInvoice Login Link',
html: `Click to login: ${baseUrl}/api/auth/verify?token=${token}`
});Benefits: No password database to secure, no reset flows to build, no credential stuffing attacks possible. Users authenticate with something they already check constantly—their email.
Invoice Management: The Core Feature Done Right
Invoicing is the heart of the application. Every feature is designed around making invoice creation fast and tracking effortless:
Creating Invoices
- Client Selection: Dropdown with existing clients or quick-add new client inline
- Dynamic Line Items: Add/remove items with automatic total calculation
- Auto-Numbering: Sequential invoice numbers with customizable prefix
- Due Date Defaults: Net 30 by default, adjustable per invoice
- Draft Mode: Save work-in-progress without sending
Invoice Status Lifecycle
enum InvoiceStatusEnum {
DRAFT // Work in progress, not sent
PENDING // Sent to client, awaiting payment
PAID // Payment received
OVERDUE // Past due date, still unpaid
}Status transitions are logged in InvoiceEvent for audit trails. Overdue status is computed automatically based on due date—no cron jobs needed.
PDF Generation
Professional PDFs generated client-side with jsPDF include:
- Business logo and contact information
- Client details with proper formatting
- Itemized table with quantities, unit prices, and line totals
- Subtotal, tax (if applicable), and grand total
- Payment instructions and terms
- Invoice number and due date prominently displayed
AI-Powered Invoice Creation: Describe It, Done
The QuickInvoiceCreator component lets users describe their work in natural language:
// User input
"Built a React dashboard with user authentication,
20 hours at $125/hour. Also set up AWS hosting, $200 flat fee."
// AI generates structured items
[
{ name: "React Dashboard Development", quantity: 20, price: 125.00 },
{ name: "User Authentication Implementation", quantity: 1, price: 0.00 },
{ name: "AWS Hosting Setup", quantity: 1, price: 200.00 }
]Claude parses the description, identifies billable items, extracts quantities and rates, and structures everything into proper invoice line items. Users review, adjust if needed, and save—cutting invoice creation time from minutes to seconds.
The prompt engineering ensures consistent output format regardless of how users describe their work. Handles hourly rates, flat fees, mixed billing, and complex project descriptions.
Financial Dashboard: Know Your Numbers
The dashboard provides instant visibility into business health:
Revenue Metrics
- • Monthly income with year-over-year comparison
- • Yearly totals and growth trends
- • Outstanding invoice amounts
- • Average invoice value
Visual Analytics
- • Monthly revenue bar charts
- • Invoice status pie chart
- • Client revenue breakdown
- • Payment timing trends
Chart.js with react-chartjs-2 renders responsive, interactive charts. Data aggregation happens at query time with Prisma's groupBy and aggregate functions—no separate analytics database needed for typical usage volumes.
Integrations: QuickBooks, Stripe, and Beyond
QuickBooks Online Sync
OAuth integration with Intuit allows syncing invoices to QuickBooks for users who need accounting software integration. The intuit-oauth package handles token management:
- Connect QuickBooks account via OAuth 2.0
- Push invoices to QBO with proper customer mapping
- Store QBO IDs for sync status tracking
- Handle token refresh automatically
Stripe Subscription Billing
Subscription management with multiple plan tiers:
- Free Tier: Limited invoices per month, basic features
- Pro Monthly/Annual: Unlimited invoices, all features, priority support
- Lifetime Deal: AppSumo codes for one-time purchase
Stripe webhooks handle subscription lifecycle: created, updated, canceled, payment failed. Usage limits reset monthly via the invoicesSentThisMonth counter.
Trigger.dev for Background Jobs
Scheduled tasks and background processing via Trigger.dev handle email reminders for overdue invoices, usage limit resets, and integration sync jobs without blocking the main application.
The Challenges and Solutions
1. Invoice Number Uniqueness
Invoice numbers must be unique per user but allow different users to have the same numbers. Solved with a composite unique constraint: @@unique([userId, number]) in Prisma. Sequential numbering with gap detection ensures no duplicates while handling deleted invoices.
2. PDF Generation Performance
Server-side PDF generation would add latency and server costs. Client-side generation with jsPDF is instant—the browser does all the work. The trade-off: PDFs can't be generated for background email attachments without a headless browser setup.
3. Magic Link Security
Magic links must be secure against interception and replay attacks. Solutions: short expiration (15 minutes), single-use tokens (invalidated after successful login), HTTPS-only transmission, and rate limiting on the login endpoint to prevent enumeration attacks.
4. Subscription Enforcement
Usage limits must be enforced reliably without blocking legitimate users. Middleware checksinvoicesSentThisMonth againstinvoiceLimit before creating invoices. Graceful degradation: users can still view and edit existing invoices when over limit.
5. Client Data Isolation
Every query must filter by userId to prevent cross-user data access. Prisma middleware could enforce this automatically, but explicitwhere: { userId } clauses in every query make the security boundary obvious in code review.
The Results: Simple Yet Powerful
Key Features
- • Magic link auth: Zero passwords
- • Invoice CRUD: Create, edit, duplicate, archive
- • Client management: Organize and track
- • PDF generation: Professional invoices instantly
- • Financial dashboard: Charts and insights
- • AI-powered creation: Natural language to invoice
Technical Wins
- • Type safety: Prisma + TypeScript
- • Fast deploys: Kubernetes on DigitalOcean
- • Secure auth: JWT magic links
- • Scalable billing: Stripe subscriptions
- • Background jobs: Trigger.dev integration
- • QBO sync: OAuth integration ready
Developer Experience Lessons
1. Magic Links Beat Passwords for SMB Apps
For tools where users log in occasionally (not daily), magic links reduce friction dramatically. No password to remember means no abandoned signups due to password requirements.
2. AI Features Need Guardrails
The QuickInvoiceCreator always shows AI-generated items for user review before saving. Never auto-commit AI output to the database—humans must verify financial data.
3. Client-Side PDF Is Underrated
jsPDF eliminates server load, reduces latency, and works offline. For user-triggered document generation, browser-based rendering is often the right choice.
4. Freemium Needs Clear Limits
Usage-based limits (invoices per month) are easier to understand and enforce than feature-based tiers. Users know exactly what they get and when they need to upgrade.
5. Audit Trails Are Worth the Storage
InvoiceEvent logs every status change. When a client claims "I never received that invoice," you have timestamped proof. Small storage cost, huge dispute resolution value.
What's Next
- Recurring Invoices: Auto-generate monthly invoices for retainer clients
- Payment Recording: Track partial payments and payment history
- Email Reminders: Automated overdue invoice notifications
- Expense Tracking: Basic expense logging for profit calculation
- Client Portal: Let clients view and pay invoices directly
- Time Tracking: Built-in timer for hourly billing
Technical Highlights
Complete Tech Stack
Frontend: Next.js 14, React 18, TypeScript, Tailwind CSS, shadcn/ui, React Hook Form
Backend: Next.js API Routes, Prisma ORM, PostgreSQL, JWT authentication
AI: Anthropic Claude for natural language invoice generation
Payments: Stripe subscriptions, webhooks, AppSumo coupon integration
Documents: jsPDF, jspdf-autotable for PDF generation
Charts: Chart.js, react-chartjs-2 for analytics
Email: Nodemailer for magic link delivery
Integrations: QuickBooks Online OAuth, Trigger.dev background jobs
Infrastructure: Kubernetes on DigitalOcean, Docker containerization
Need a Custom Business Tool?
If you're looking for an engineer who can build focused, production-ready applications with clean architecture and modern tooling, let's talk.