A secure, TypeScript-based web application that generates QR codes from URLs or vCard contact information, with optional logo embedding. Features a modern web interface for easy use and a RESTful API for integration. Designed for easy self-hosting and open-source usage.
- Generate QR codes from valid URLs
- Create vCard QR codes with comprehensive contact information
- Optional PNG/SVG logo embedding in QR codes
- Multiple phone numbers, emails, and websites support
- Profile saving and loading with local browser storage
- Responsive web interface with collapsible sections
- RESTful API with comprehensive validation
- Security hardened with rate limiting, input validation, and security headers
- Docker support for easy deployment
# Clone the repository
git clone https://github.com/yourusername/qr-code-generator.git
cd qr-code-generator
# Install dependencies
npm install
# Start development server
npm run dev
# Or build and run
npm run build
npm startThe server will start on http://localhost:3000
# Build the Docker image
docker build -t qr-code-generator .
# Run the container
docker run -p 3000:3000 qr-code-generatorPORT: Server port (default: 3000)
Generate a QR code from a URL with optional logo embedding.
Request:
- Content-Type:
multipart/form-data - Body:
url(required): Valid HTTP/HTTPS URL (max 2048 characters)logo(optional): PNG, JPEG, or SVG image file (max 5MB)
Response:
- Content-Type:
image/png - Body: QR code image data
Rate Limit: 100 requests per 15 minutes per IP
Examples:
Using curl:
curl -X POST http://localhost:3000/generate-qr \
-F "url=https://example.com" \
-o qr-code.pngWith logo:
curl -X POST http://localhost:3000/generate-qr \
-F "url=https://example.com" \
-F "[email protected]" \
-o qr-code-with-logo.pngUsing JavaScript/fetch:
const formData = new FormData();
formData.append('url', 'https://example.com');
(async () => {
const response = await fetch('/generate-qr', {
method: 'POST',
body: formData
});
const blob = await response.blob();
// Handle the QR code image
})();Error Responses:
400 Bad Request: Invalid URL or file format/size429 Too Many Requests: Rate limit exceeded500 Internal Server Error: Server error
Generate a QR code from vCard contact information with optional logo embedding.
Request:
- Content-Type:
multipart/form-data - Body:
name(required): Full namecontact[](optional): Phone numbers (multiple allowed)email[](optional): Email addresses (multiple allowed)company(optional): Company namestreet(optional): Street addresscity(optional): Citycountry(optional): Countrywebsite[](optional): Websites (multiple allowed)note(optional): Additional notestitle(optional): Job titlerole(optional): Professional rolenickname(optional): Nicknamebirthday(optional): Date of birthlogo(optional): PNG, JPEG, or SVG image file (max 5MB)
Response:
- Content-Type:
image/png - Body: vCard QR code image data
Rate Limit: 100 requests per 15 minutes per IP
Examples:
Using curl:
curl -X POST http://localhost:3000/generate-vcard-qr \
-F "name=John Doe" \
-F "contact[]=123-456-7890" \
-F "email[][email protected]" \
-o vcard-qr.pngUsing JavaScript/fetch:
const formData = new FormData();
formData.append('name', 'John Doe');
formData.append('contact[]', '123-456-7890');
formData.append('email[]', '[email protected]');
(async () => {
const response = await fetch('/generate-vcard-qr', {
method: 'POST',
body: formData
});
const blob = await response.blob();
// Handle the QR code image
})();Error Responses:
400 Bad Request: Invalid input data or file format/size429 Too Many Requests: Rate limit exceeded500 Internal Server Error: Server error
- Rate Limiting: 100 requests per 15 minutes per IP
- Input Validation: URL format and length validation
- File Upload Security: Type and size restrictions (PNG/JPEG/SVG, 5MB max)
- Security Headers: Helmet.js with CSP, HSTS, etc.
- Error Handling: Comprehensive error responses without information leakage
-
Build the image:
docker build -t qr-code-generator . -
Run with environment variables:
docker run -p 8080:3000 -e PORT=3000 qr-code-generator
- Install Node.js 18+
- Clone and install dependencies
- Build the project:
npm run build - Start with PM2 or similar:
pm2 start dist/index.js
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
MIT License - see LICENSE file for details.