Made with ❤️ by Peter Shaan.
OpenQRCard – an open-source, self-hosted digital business card & QR code manager.
OpenQRCard lets you create digital business cards that open from a QR code. Each person gets a public profile page (/your-id) with their name, title, phone numbers, emails, social links and a Save to Contacts button that downloads a vCard.
Built with React Router v7 (SSR), React 19, TailwindCSS 4, DaisyUI and MySQL. Ships with Docker Compose so you can self-host it on any server in minutes.
Great for companies, teams, events, or anyone who wants their own Linktree-style contact card without paying for a SaaS.
- QR Code Generation: Every card gets a QR code (via
qrcode.react) ready to print or share. - Public Profile Card: Mobile-friendly card page at
/:id— no login needed for visitors. - vCard Download: One tap "Save to Contacts" (
/:id/vcard). - Live Phone Preview: See changes in a phone mockup while editing.
- Multiple Contacts: Add multiple phone numbers, emails and social links (Instagram, LinkedIn, WhatsApp, TikTok, YouTube, etc.).
- Theme System: Create brand themes with primary color and legal/footer text, then apply them per card.
- User Management: Admin dashboard to manage users and roles.
- Scan Counter: Track how many times each card was opened.
- Draft / Published: Keep cards private until ready.
- Docker Ready:
docker compose upand you're live.
-
Clone the repository:
git clone https://github.com/kerenkok10/qr-code.git cd qr-code npm install -
Set up environment variables: copy
.env.exampleto.envand fill in your own values.cp .env.example .env
Variable Description MYSQL_ROOT_PASSWORDMySQL root password (used by the app too) MYSQL_DATABASEDatabase name SESSION_SECRETRandom string for signing session cookies ( openssl rand -hex 32) — requiredMYSQL_PORTMySQL port exposed on host APP_PORTApp port inside the container APP_PUBLIC_PORTApp port exposed on host When running without Docker, the app reads
DB_HOST,DB_PORT,DB_USER,DB_PASSWORD,DB_NAMEandSESSION_SECRET. -
Create the database: import the schema (and optional seed data) from
database/init.sql.mysql --default-character-set=utf8mb4 -u root -p your_database < database/init.sql -
Run the project:
npm run dev
Open http://localhost:5173 and log in with the seeded admin account:
admin@example.com/password. You will be asked to set a new password on first login. Logins are limited to 5 failed attempts per 15 minutes. -
Deploy with Docker:
docker compose up -d --build docker exec -i qrcard_mysql sh -c 'mysql --default-character-set=utf8mb4 -uroot -p"$MYSQL_ROOT_PASSWORD" "$MYSQL_DATABASE"' < database/init.sql
The app is now running on
http://localhost:3001(or yourAPP_PUBLIC_PORT). Put it behind Nginx with HTTPS for production — see DEPLOYMENT.md for a full guide.
| Login | Dashboard |
|---|---|
![]() |
![]() |
| Card Editor + Live Preview | Public Card |
![]() |
![]() |
Don't have a VPS or Docker? The php branch has the same app as a static React + Vite frontend with a PHP 7.4+ backend, so it runs on cheap shared hosting (cPanel, Hostinger, Niagahoster, etc.) with just Apache + MySQL.
-
Checkout the branch:
git clone -b php https://github.com/kerenkok10/qr-code.git qr-code-php cd qr-code-php npm install -
Run locally (needs Node.js 20+ and PHP):
npm run dev:full
Open http://localhost:3000.
-
Create
.envwith your hosting database:VITE_API_URL="/php-backend/api.php" DB_HOST="localhost" DB_PORT="3306" DB_NAME="your_database" DB_USER="your_db_user" DB_PASSWORD="your_db_password"
-
Build and zip:
npm run build mkdir deployment cp -R dist/. deployment/ cp -R php-backend deployment/ cp .htaccess .env deployment/ (cd deployment && zip -r ../qr-code-production.zip .) -
Upload
qr-code-production.zipin cPanel File Manager and extract it directly insidepublic_html(not inside a subfolder):public_html/ ├── .env ├── .htaccess ├── assets/ ├── php-backend/ └── index.html -
Create the database: in cPanel → MySQL Databases, create a database + user, then open phpMyAdmin → Import →
database/init.sql. -
Done! Open your domain and log in with
admin@example.com/password. You will be asked to set a new password on first login.
Full details (SQL schema, API endpoints) are in the php branch README.
| Route | Access | Description |
|---|---|---|
/login |
Public | Admin / user login |
/dashboard |
Logged in | List, search and filter your QR cards |
/create-qrcode, /edit-qrcode/:id |
Logged in | Card editor with live preview |
/theme |
Logged in | Manage brand themes |
/users |
Admin | Manage users |
/:id |
Public | Public profile card |
/:id/vcard |
Public | Download vCard |
- Themes: create your own brand colors and footer text from the
/themepage. - Social icons: replace the images in
public/(ig.png,facebook.png,tiktok.png,yt.png,pinterest.png). - Public card layout: edit
app/routes/public-card.tsx. - Styling: TailwindCSS + DaisyUI in
app/app.css. - Seed data: edit
database/init.sqlto change the default admin, themes and sample card.
This project is open to contributions. Feel free to fork it, improve it, or submit pull requests with new features or fixes.
This project is provided under the MIT License. You are free to use, modify, and distribute it.



