Modern Invoice Generator Lite
— Angular 21
A professional, frontend-only invoice generation application. Create, customize, and export beautiful invoices entirely in the browser — no backend required.
Introduction
01Modern Invoice Generator Lite is a fully frontend, browser-based invoice generation application built with Angular 21. It requires no server, no database, and no backend — making it trivial to deploy anywhere that can serve static files.
The application lets users build polished, professional invoices in minutes and export them as PDF files or send them directly to print. All data is persisted automatically via the browser's LocalStorage, so nothing is ever lost on refresh.
What you can do with it
Create Invoices
Professional invoices with auto-numbered IDs and due dates
Company Branding
Add logo, name, address, phone, email and website
Smart Totals
Subtotal, tax, and grand total computed in real time
PDF Export
One-click PDF download with pixel-perfect layout
Multi-Currency
Switch between USD, EUR, GBP, INR, AUD, CAD instantly
Signature Line
Add authorized-by name with optional signature image
This is a Lite edition. All features are fully functional and production-ready. The application is entirely self-contained — just build and deploy.
Features
02A complete overview of every feature included in this product.
Create Invoices
Full invoice editor with all standard fields
Line Items
Add unlimited items with description, qty, unit price
Auto Totals
Subtotal, tax amount, and grand total computed live
Tax Rate
Configurable tax percentage applied to subtotal
Multi Currency
USD · INR · EUR · GBP · AUD · CAD
Logo Upload
Company logo stored as Base64 in LocalStorage
Bill To / Ship To
Separate shipping address with toggle
Invoice Notes
Custom note / payment terms text block
Print Invoice
Browser print with print-optimized CSS styles
PDF Export
Download as PDF via html2pdf.js
Responsive
Works on desktop, tablet, and mobile
Auto Save
LocalStorage auto-save — never lose your work
Authorized By
Signature name + optional signature image
Invoice Numbers
Auto-incrementing invoice numbers
Technology Stack
03Modern Angular 21 Patterns
This project uses the latest Angular features and architectural patterns:
| Pattern | Description |
|---|---|
signal() & computed() | Reactive state without Zone.js — the entire invoice state is signal-based |
effect() | Auto-save side effect: whenever the invoice signal changes, it saves to LocalStorage |
| Standalone Components | No NgModule anywhere — every component is standalone |
| Zoneless Change Detection | provideZonelessChangeDetection() for best performance |
| Native Control Flow | @if, @for, @switch — no structural directives |
| Lazy-loaded Routes | loadChildren() for / (invoice) and /settings |
| Dynamic Import | html2pdf.js is dynamically imported — only loaded when the user clicks Export PDF |
Folder Structure
04The project follows Angular's recommended feature-based folder structure.
src/
├── app/
│ ├── core/ # Singleton services & data models
│ │ ├── models/
│ │ │ └── invoice.model.ts # All TypeScript interfaces & defaults
│ │ └── services/
│ │ ├── invoice.service.ts # Central signal-based state store
│ │ ├── storage.service.ts # LocalStorage read/write abstraction
│ │ └── pdf-export.service.ts # html2pdf.js lazy loader & export
│ │
│ ├── features/ # Lazy-loaded route features
│ │ ├── invoice/
│ │ │ ├── invoice.routes.ts
│ │ │ ├── pages/invoice-page/ # Root invoice page layout
│ │ │ └── components/
│ │ │ ├── invoice-editor/ # Left panel — all form inputs
│ │ │ ├── invoice-items/ # Line items table with add/remove
│ │ │ └── invoice-preview/ # Right panel — live PDF-ready preview
│ │ └── settings/
│ │ ├── settings.routes.ts
│ │ └── pages/settings-page/ # Company info, currency, tax rate
│ │
│ ├── shared/ # Reusable components
│ │ └── components/
│ │ ├── navbar/ # Top nav — New Invoice, Print, Export PDF
│ │ └── logo-upload/ # Drag-and-drop logo uploader
│ │
│ ├── app.ts # Root component
│ ├── app.html # Root template (<router-outlet>)
│ ├── app.routes.ts # Top-level lazy routes
│ └── app.config.ts # provideZonelessChangeDetection, Router
│
├── styles/ # Global SCSS design system
│ ├── _variables.scss # Color tokens, spacing, typography
│ ├── _mixins.scss # Reusable SCSS helpers
│ ├── _buttons.scss
│ ├── _forms.scss
│ ├── _layout.scss
│ └── _invoice.scss # Invoice preview print styles
│
├── styles.scss # Global stylesheet entry
└── types/
└── html2pdf.d.ts # TypeScript declarations for html2pdf.js
Key Files Explained
| File | Purpose |
|---|---|
invoice.service.ts | The single source of truth. All invoice state lives here as an Angular signal(). Auto-saves on every change via effect(). |
storage.service.ts | Thin wrapper around localStorage. Handles serialization, invoice number counter, and key management. |
pdf-export.service.ts | Registers the preview DOM element via registerPreviewElement() and triggers PDF export. html2pdf.js is dynamically imported here. |
invoice-preview.html | The print/PDF layout. Rendered from signal data — what you see is what gets exported. |
_invoice.scss | Print-specific CSS. Controls the PDF layout, fonts, and page margins. |
Installation
05Follow these steps to get the project running on your local machine.
Install Node.js
Download and install Node.js version 22 or later (LTS recommended) from nodejs.org. Verify your installation:
node --version
# Should output v22.x.x or higher
npm --version
# Should output 10.x.x or higher
Angular 21 requires Node.js 22+. If you have an older version, use nvm (Node Version Manager) to switch versions.
Install Angular CLI
Install the Angular CLI globally on your machine. You only need to do this once.
npm install -g @angular/cli
Verify the installation:
ng version
Extract the Project Files
Extract the downloaded ZIP archive and open a terminal inside the project folder. You should see package.json in the current directory.
Install Dependencies
Install all Node.js dependencies. The --legacy-peer-deps flag handles any peer dependency version mismatches gracefully.
npm install --legacy-peer-deps
This will install Angular, TypeScript, html2pdf.js, and all other required packages into the node_modules folder.
Running the Project
06Start the Angular development server with live reload.
ng serve
Once the server starts, open your browser and navigate to:
http://localhost:4200
The dev server features hot module replacement (HMR). Any file changes are reflected in the browser instantly without a full page reload.
Application Routes
| Route | Page | Description |
|---|---|---|
/ | Invoice Editor | Main invoice editor with live preview pane |
/settings | Settings | Company info, default currency, and tax rate |
Build for Production
07Create an optimized production build with tree-shaking, minification, and code splitting.
ng build --configuration production
The compiled output is placed in the /dist directory at the project root. The contents of this folder are what you deploy.
The production build applies tree-shaking, Ahead-of-Time (AOT) compilation, and code splitting for the best possible performance and bundle size.
Deployment
08Since this is a pure static application, it can be hosted on any static file hosting provider.
Deploy to Netlify (Recommended)
Option A — Drag & Drop (quickest)
Build the project
ng build --configuration production
Upload to Netlify
Go to netlify.com → drag and drop the contents of dist/morden-invoice-generator/browser/ onto the Netlify dashboard. Your site is live instantly.
Option B — Git-Connected Auto Deploy
Connect your Git repository to Netlify
In Netlify dashboard, click New site from Git and connect your GitHub/GitLab/Bitbucket repository.
Configure build settings
Build command: ng build --configuration production
Publish directory: dist/morden-invoice-generator/browser
Add _redirects file for SPA routing
Place a _redirects file inside src/ (it will be copied to dist) with this content:
/* /index.html 200
This ensures Angular's client-side router handles all URL paths correctly.
With Git-connected deploys, every push to your main branch automatically triggers a new build and deploys the latest version within seconds.
Configuration
09Configuration is done entirely through the application's Settings page (/settings). No code changes are needed for basic configuration. All settings are persisted automatically in LocalStorage.
Settings Page Fields
| Field | Description | Default |
|---|---|---|
| Company Name | Displayed in the invoice header | Your Company Name |
| Address | Multi-line company address | 123 Business Avenue… |
| Phone | Contact phone number | +1 (555) 000-0000 |
| Company email address | hello@yourcompany.com | |
| Website | Company website URL | www.yourcompany.com |
| Logo | Company logo image (PNG/JPG/SVG, stored as Base64) | None |
| Default Currency | Currency shown on new invoices | USD |
| Default Tax Rate | Pre-filled tax % on new invoices | 0% |
Per-Invoice Configuration
Each invoice also has its own editable fields on the main invoice editor page:
| Field | Description |
|---|---|
| Invoice Number | Auto-incremented, but editable |
| Invoice Date | Defaults to today's date |
| Due Date | Defaults to 30 days from today |
| Bill To | Client name, address, email, phone |
| Ship To | Optional separate shipping address (toggle to show) |
| Currency | Per-invoice currency override |
| Tax Rate | Per-invoice tax percentage |
| Notes | Payment terms or custom message |
| Authorized By | Name shown under the signature line |
Customization
10Developers can customize the look and feel of both the application UI and the invoice layout by editing the SCSS files.
Design Tokens — src/styles/_variables.scss
All colors, spacing, and typography values are defined as SCSS variables here. Change these to re-theme the entire application:
// Brand colors — change these to re-theme the app
$primary: #6366f1; // Indigo — buttons, links, accents
$primary-dark: #4f46e5; // Hover state
$accent: #22d3ee; // Cyan highlights
// Invoice layout colors
$invoice-header-bg: #1e2535;
$invoice-border: #2a3144;
$invoice-text: #f1f5f9;
// Typography
$font-base: 'Inter', system-ui, sans-serif;
$font-mono: 'JetBrains Mono', monospace;
Invoice Print Layout — src/styles/_invoice.scss
This file controls how the invoice looks when printed or exported as PDF. Edit it to match your brand:
// Invoice preview wrapper
.invoice-preview {
background: #fff;
color: #1a1a2e;
font-family: 'Inter', sans-serif;
max-width: 794px; // A4 width in px at 96dpi
padding: 40px 48px;
}
// Header section with company info + logo
.invoice-header {
display: flex;
justify-content: space-between;
margin-bottom: 32px;
}
// Customize the accent color of table headers
.invoice-table thead th {
background: $primary;
color: #fff;
}
SCSS File Overview
| File | What to customize |
|---|---|
_variables.scss | Colors, fonts, spacing tokens — start here |
_invoice.scss | Invoice layout, print styles, PDF appearance |
_buttons.scss | Button styles and hover states |
_forms.scss | Input, select, textarea styles |
_layout.scss | App shell, split-pane editor layout |
The project uses @use 'sass:color' with color.adjust() for all color manipulations — no deprecated darken() or lighten() functions. This ensures full compatibility with modern Sass.
Currency Support
11The application ships with six currencies out of the box. The selected currency symbol is displayed throughout the invoice — in item prices, subtotal, tax, and grand total.
| Currency | Code | Symbol |
|---|---|---|
| US Dollar | USD | $ |
| Indian Rupee | INR | ₹ |
| Euro | EUR | € |
| British Pound | GBP | £ |
| Australian Dollar | AUD | A$ |
| Canadian Dollar | CAD | C$ |
Adding a New Currency
To add a new currency, open src/app/core/models/invoice.model.ts and add an entry to the CURRENCIES array:
export const CURRENCIES: CurrencyOption[] = [
{ code: 'USD', symbol: '$', name: 'US Dollar' },
{ code: 'INR', symbol: '₹', name: 'Indian Rupee' },
{ code: 'EUR', symbol: '€', name: 'Euro' },
{ code: 'GBP', symbol: '£', name: 'British Pound' },
{ code: 'AUD', symbol: 'A$', name: 'Australian Dollar' },
{ code: 'CAD', symbol: 'C$', name: 'Canadian Dollar' },
// Add your currency here:
{ code: 'JPY', symbol: '¥', name: 'Japanese Yen' },
];
The new currency will automatically appear in the currency dropdown on both the invoice editor and the settings page.
Printing & PDF Export
12Print Invoice
Click the Print button in the top navigation bar. The application applies print-optimized CSS that hides the editor pane and displays only the invoice preview, perfectly formatted for your printer.
Export as PDF
Click the Export PDF button in the navigation bar. The PDF is generated entirely in the browser using html2pdf.js + html2canvas. The file is named after the invoice number (e.g., invoice-INV-0001.pdf).
How it works internally
| Step | What happens |
|---|---|
| 1. User clicks Export PDF | NavbarComponent calls PdfExportService.exportToPdf(invoiceNumber) |
| 2. Lazy load | PdfExportService dynamically imports html2pdf.js (first time only) |
| 3. Capture DOM | html2canvas converts the #invoice-preview DOM element to a canvas |
| 4. Generate PDF | The canvas is embedded into a PDF document with correct A4 page sizing |
| 5. Download | The browser triggers a file download with the filename invoice-[number].pdf |
PDF Quality Settings
PDF quality and page settings can be adjusted in src/app/core/services/pdf-export.service.ts:
const options = {
margin: [8, 8, 8, 8], // top, right, bottom, left (mm)
filename: `invoice-${invoiceNumber}.pdf`,
image: { type: 'jpeg', quality: 0.98 },
html2canvas: { scale: 2, useCORS: true }, // scale: 2 = retina quality
jsPDF: { unit: 'mm', format: 'a4', orientation: 'portrait' },
};
Troubleshooting
13Common issues and their solutions. Click any item to expand.
Angular CLI is not installed or not in your system PATH. Run:
npm install -g @angular/cli
If you're on Windows and it still doesn't work, try restarting your terminal or running it as Administrator.
Angular 21 requires Node.js 22 or later. Check your current version:
node --version
To upgrade, use nvm (Node Version Manager):
nvm install 22
nvm use 22
This can happen when npm's strict peer dependency resolution conflicts. Use the legacy flag:
npm install --legacy-peer-deps
If that still fails, try clearing the npm cache first:
npm cache clean --force
npm install --legacy-peer-deps
Another process is using port 4200. Start the dev server on a different port:
ng serve --port 4300
This can happen due to cross-origin font loading. Make sure the app is served from a proper domain (not file://). When running locally, use ng serve — don't open the index.html file directly in the browser.
For production, ensure your hosting provider serves assets with appropriate CORS headers.
The app uses localStorage for persistence. Check if:
- Your browser has LocalStorage enabled (not in private/incognito mode with restrictions)
- The browser's storage quota has not been exceeded
- You haven't clicked "Clear All Data" in the app
Support
14Need help? We're here for you.
If you have questions about setup, customization, or run into any issues, don't hesitate to reach out. We typically respond within 24 hours on business days.
Before contacting support
Please check the following first to speed up resolution:
| Check | How |
|---|---|
| Node.js version | Run node --version — must be 22+ |
| Angular CLI version | Run ng version — should match Angular 21 |
| Dependencies installed | Ensure node_modules exists and npm install --legacy-peer-deps completed without fatal errors |
| Error message | Copy the full error from the terminal or browser console |
If you find this product helpful, please consider leaving a 5-star rating on CodeCanyon. It helps a lot and is greatly appreciated!
Modern Invoice Generator Lite · Angular 21 · v1.0.0
© 2026 · All rights reserved · Licensed per CodeCanyon Standard/Extended License