# PNGer Development & Technical Instructions ## Project Overview PNGer is a single-container web application for PNG editing and resizing, designed for deployment on Unraid with Gitea version control. It features a modern Svelte frontend and a high-performance Node.js/Sharp backend. ## Technical Architecture ### Architecture Overview PNGer uses a multi-layered architecture designed for responsiveness and efficiency: ```mermaid graph TD A[User Browser] --> B[Svelte Frontend] B --> C[Canvas API (Live Preview)] B --> D[Express API (Backend)] D --> E[Sharp Image Library] D --> F[Runtime Environment (Docker)] ``` ### Backend (Express + Sharp) The backend is built with Node.js and TypeScript, using Express for the API and Sharp for high-performance image processing. **Key Endpoints:** - `POST /api/transform` - Transform image (resize, crop, compress, convert) - `GET /api/health` - Health check **Key Dependencies:** - `sharp`: High-performance image processing (handles resizing, cropping, and format conversion). - `multer`: Middleware for handling `multipart/form-data`, used for file uploads. - `express`: Web framework for the API. ### Frontend (Svelte + Vite) The frontend is a reactive Svelte application that prioritizes real-time feedback and UX. **Core Components & Modules:** - `App.svelte`: Main application container managing state and UI. - `lib/api.ts`: API client for backend communication. - `lib/preview.ts`: Client-side preview logic using the Canvas API for instant feedback. - `lib/theme.ts`: Dark/light theme management with persistent storage. - `lib/presets.ts`: Configuration for smart image presets. ### Design System (Dark/Light Modes) The UI uses a modern design system with CSS custom properties for theming: - **Light Mode**: Clean white background with dark gold (`#b8860b`) accents. - **Dark Mode**: Deep black (`#0a0a0a`) background with light gold (`#daa520`) accents. - **Transparencies**: Dark/Light toggling allows users to inspect PNG transparency against different backgrounds. ## Implementation Details ### Live Preview System Live preview is implemented using a client-side Canvas-based approach to provide instant feedback (< 100ms) without server round-trips. **How it works:** 1. User uploads an image. 2. The browser loads the image into an HTML5 Canvas. 3. On any parameter change (width, quality, etc.), a debounced (300ms) update applies transformations to the canvas. 4. The canvas content is displayed side-by-side with the original for comparison. 5. File sizes are estimated from the Canvas data URL to provide immediate feedback on optimization savings. ### Docker Strategy & Fixes PNGer uses a multi-stage Docker build to minimize image size and maximize security. **Optimization Fixes applied:** - **Dependency Installation**: Uses `npm install` instead of `npm ci` to handle missing lockfiles gracefully while maintaining stability via caret ranges in `package.json`. - **Security**: Runs as a non-root `node` user in the final Alpine-based image. - **Multer Upgrade**: Upgraded to `v2.1.0` for improved security and performance. ## Local Development Setup ### Prerequisites - Node.js 20+ - npm or pnpm - Docker (optional) ### Setup Steps ```bash # Clone repository git clone https://git.alwisp.com/jason/pnger.git cd pnger # Setup backend cd backend npm install npm run dev # Setup frontend (separate terminal) cd frontend npm install npm run dev ``` ### Environment Variables **Backend (.env):** - `PORT`: 3000 (internal) - `MAX_FILE_SIZE`: 10485760 (10MB default) - `CORS_ORIGIN`: http://localhost:5173 **Frontend (.env):** - `VITE_API_URL`: http://localhost:3000/api ## Development Workflow & Standards ### Workflow 1. **Feature Branch**: Create from `main`. 2. **Develop**: Use hot-reload (`npm run dev`). 3. **Test**: Perform manual testing of image operations and presets. 4. **Commit**: Use `type: description` format (e.g., `feat: add rotation`). 5. **Merge**: Merge into `main` after review. ### Code Standards - **TypeScript**: Use strict types where possible. - **Svelte**: Keep components modular and under 300 lines. - **Async/Await**: Use for all asynchronous operations. - **Semantic HTML**: Ensure accessibility and proper structure. ## Troubleshooting - **Port in use**: `lsof -ti:3000 | xargs kill -9` - **Sharp issues**: `npm rebuild sharp` - **Docker Cache**: `docker builder prune` if builds fail unexpectedly. - **Preview Glitches**: Check browser console for Canvas API errors. --- **Last Updated**: March 12, 2026