Design and generate ID cards in bulk with a Canva-style editor, CSV automation, and server-side rendering.
QuicKards is a production-focused SaaS starter for colleges, festivals, events, and orgs that need fast, branded ID card generation at scale.
- Drag-and-drop template editor (Fabric.js)
- CSV import with robust field matching
- Single image and ZIP image mapping by
card_id - Batch preview + full render pipeline
- PDF + ZIP output generation
- Authenticated multi-user backend with Appwrite
- Auto-expiry policy for projects/templates (36 hours)
- Frontend: Next.js (App Router), React, Tailwind CSS, Framer Motion
- Editor: Fabric.js
- Backend: Next.js Route Handlers (
/api/v1) - Storage + Auth + DB: Appwrite
- Rendering: sharp, pdf-lib, archiver, qrcode
- Install dependencies
npm install- Create environment file
cp .env.example .env.local-
Fill
.env.localwith Appwrite values (project, endpoint, API key, DB/bucket IDs) -
Bootstrap Appwrite resources
node --env-file=.env.local ./scripts/setup-appwrite.mjs- Run locally
npm run devApp runs at http://localhost:3000.
Core values expected by QuicKards:
NEXT_PUBLIC_APPWRITE_ENDPOINTNEXT_PUBLIC_APPWRITE_PROJECT_IDAPPWRITE_API_KEYAPPWRITE_DATABASE_IDAPPWRITE_TEMPLATES_COLLECTION_IDAPPWRITE_PROJECTS_COLLECTION_IDAPPWRITE_CARD_DATA_COLLECTION_IDAPPWRITE_ASSETS_COLLECTION_IDAPPWRITE_JOBS_COLLECTION_IDAPPWRITE_TEMPLATE_BUCKET_IDAPPWRITE_IMAGE_BUCKET_IDAPPWRITE_OUTPUT_BUCKET_IDAPPWRITE_SESSION_COOKIE_NAME
Base path: /api/v1
- Auth:
POST /auth/signin,POST /auth/signup,POST /auth/signout,GET /auth/me - Templates:
POST/GET /templates,GET/PATCH/DELETE /templates/:id,POST /templates/:id/background - Projects:
POST/GET /projects,GET/DELETE /projects/:id - CSV Data:
POST/GET /projects/:id/data - Images:
POST /projects/:id/images/zip,POST /projects/:id/images,GET /projects/:id/images/:card_id - Rendering:
POST /projects/:id/preview,POST /projects/:id/render,GET /jobs/:job_id - Downloads:
GET /downloads/:file_id
- Rendering is server-side only (no client rendering pipeline).
- Keep Appwrite tables/buckets private; access is enforced through authenticated API handlers.
- Output file IDs are stored in job records and streamed through
/api/v1/downloads/:file_id. - If your Appwrite plan limits bucket count, you can reuse one bucket by pointing all three bucket env vars to the same ID.
npm run dev– local dev servernpm run lint– lintingnpm run build– production buildnpm run start– run production build