Architecture Overview
Relevant source files
The following files were used as context for generating this wiki page:
The QR-Tool is a client-side single-page application (SPA) built with React and Vite. Its primary purpose is to provide a user-friendly interface for generating and customizing various types of QR codes. The architecture is centered around a main App component that manages all application state, user input, and business logic. All processing, from data validation to QR code rendering and exporting, occurs entirely within the user's browser, requiring no backend server.
The application's design emphasizes a reactive data flow, where user modifications in the control panel immediately trigger updates in the state, which in turn re-renders the QR code preview. It leverages custom hooks for managing persistent UI settings and a modular structure with distinct components for UI controls, QR preview, and export functionality. Security is handled through comprehensive input validation and a strict Content Security Policy (CSP).
Sources: README.md, src/App.jsx
Technology Stack
The project is built upon a modern JavaScript ecosystem, focusing on performance and developer experience. The core technologies are defined in the package.json file.
| Technology | Version | Role |
|---|---|---|
| React | 19.2.0 | UI Framework |
| Vite | rolldown-vite | Build Tool & Dev Server |
| Tailwind CSS | 3.4.18 | Utility-First CSS Framework |
| qrcode.react | 4.2.0 | Core QR Code Generation Library |
| @zxing/browser | 0.1.5 | QR Code Scanning for Validation |
| Vitest | 4.0.8 | Unit Testing Framework |
| ESLint | 9.39.1 | Code Linting |
Sources: package.json, README.md
Project Structure
The project follows a standard structure for a Vite-based React application. Key logic is separated into components, hooks, and utility functions within the src/ directory.
This diagram illustrates the high-level directory structure of the project.
Sources: README.md
Component Architecture
The application is composed of a main parent component (App) that orchestrates several child components responsible for specific UI sections.
This diagram shows the hierarchy of the main React components.
App.jsx
This is the central component of the application. It is responsible for:
- Managing the entire application state, including QR type, data, and all customization options (
size,fgColor,bgColor,level, etc.). - Handling all user interactions and updating the state accordingly.
- Implementing input validation logic and displaying error messages.
- Generating the final QR code content string via the
generateQRContentfunction. - Passing props down to child components (
QrPreview,ExportPanel).
Sources: src/App.jsx
QrPreview.jsx
This component is responsible for rendering the visual representation of the QR code.
- It receives all QR properties (
qrProps) from theAppcomponent. - It conditionally renders either a
<QRCodeCanvas>or<QRCodeSVG>component from theqrcode.reactlibrary based on the selected format. - It handles the drag-and-drop functionality for uploading a logo.
Sources: src/components/QrPreview.jsx
ExportPanel.jsx
This component provides the UI and logic for downloading the generated QR code.
- It contains buttons to export as PNG, JPG, or SVG.
- It uses helper functions from
qr-helpers.js(buildDataURL,buildSVGBlob,downloadFile) to process and trigger the file download. - It handles logic for adding padding (a "Quiet Zone") if the user has disabled the default margin.
Sources: src/components/ExportPanel.jsx
State Management and Data Flow
State is managed locally within the App.jsx component using React's useState hook. For UI preferences that need to be persisted across sessions, a custom useLocalStorage hook is employed.
State Management
qrType: Stores the selected type of QR code (e.g., 'url', 'text', 'wifi').qrData: An object containing the specific data for the selectedqrType(e.g.,{ url: '...' },{ ssid: '...', password: '...' }).- Customization State: Multiple state variables for UI options like
size,fgColor,bgColor,eccMode,logoUrl,format, etc. useLocalStorageHook: A wrapper arounduseStatethat automatically reads from and writes to the browser'slocalStorage. This is used for all customization options to remember user settings.
Sources: src/App.jsx:274-276, src/App.jsx:324-345
Data Flow
The application follows a unidirectional data flow, typical for React applications.
The following flowchart shows the process from user interaction to the final QR code preview.
Sources: src/App.jsx:304-322, src/App.jsx:500-517
Core Logic and Utilities
Most of the business logic and helper functions are abstracted into src/utils/qr-helpers.js to keep the App component cleaner and to facilitate testing.
QR Content Generation
The generateQRContent function in App.jsx is responsible for formatting the raw data from the state into the specific string format required by the QR code standard for each type.
// src/App.jsx:61-127
const generateQRContent = (type, data) => {
switch (type) {
case QR_TYPES.URL:
return data.url || 'https://example.com';
case QR_TYPES.WIFI: {
const T = data.encryption || 'WPA';
const S = escWiFi(data.ssid || '');
const parts = [`WIFI:T:${T};S:${S};`];
// ... more logic
return parts.join('');
}
case QR_TYPES.VCARD: {
const lines = [
'BEGIN:VCARD',
'VERSION:3.0',
// ... more fields
];
return lines.join('\r\n');
}
// ... other cases
}
};
This logic is validated by unit tests in tests/qr-helpers.test.js.
Sources: src/App.jsx:61-127, src/App.test.js
Utility Functions (qr-helpers.js)
This file contains a collection of pure functions used throughout the application.
| Function | Description |
|---|---|
isValidURL, isValidEmail, etc. | A set of functions to validate user input for different QR types. |
relLum, getContrastRatio | Calculates relative luminance and WCAG contrast ratio between two hex colors. |
normalizeHex, isValidHex | Normalizes and validates hex color code formats. |
pickECC | Automatically selects the optimal Error Correction Code (ECC) level based on logo size and color contrast. |
estimateDimension | Estimates the required QR code version (size in modules) based on data length and ECC level. |
buildDataURL | Creates a data URL for a PNG/JPG from a canvas, with options for padding and rounded corners. |
buildSVGBlob | Creates a Blob for an SVG file, with options for padding and background color. |
downloadFile | Triggers a browser file download from a data URL or Blob. |
Sources: src/utils/qr-helpers.js, tests/qr-helpers.test.js
Export Process
The export functionality is handled by ExportPanel.jsx and relies on utilities from qr-helpers.js.
This sequence diagram illustrates the flow when a user clicks a download button.
Security
The application is designed to be secure for a client-side tool.
- Input Validation: All user-provided data that forms the QR content is validated to prevent malformed QR codes. Specific checks are in place for URLs, emails, phone numbers, and coordinates.
- XSS Protection: By using React, the application benefits from its built-in output escaping, which prevents raw HTML from being injected into the DOM, thus mitigating XSS risks.
- File Upload Security: Logo uploads are validated by file type (PNG, JPG, WebP, SVG) and size (max 4MB) on the client side.
- Content Security Policy (CSP): A strict CSP is defined in
public/_headersto restrict resource loading, mitigating risks of cross-site scripting and data injection attacks.
Sources: SECURITY_AUDIT_REPORT.md, src/App.jsx:304-322, 614-633, src/utils/qr-helpers.js:29-87