mini-crm is a lightweight Customer Relationship Management (CRM) app built as a monorepo with a Node.js/Express API and a React/Vite frontend. It supports user authentication, contact management, tagging, search, pagination, and CSV export.
- Email/password authentication (JWT)
- Contact CRUD with search and pagination
- Tag management and tag assignment per contact
- CSV export of contacts
- Dockerized deployment with Traefik reverse proxy
- Backend: Node.js, Express, PostgreSQL, Prisma
- Frontend: React, Vite, React Router
- Containerization: Docker
- Reverse Proxy: Traefik
mini-crm
├── apps
│ ├── backend
│ └── frontend
├── docker
├── package.json
├── package-lock.json
└── README.md
- Node.js 18+ and npm
- PostgreSQL (for local development)
- Docker + Docker Compose (for containerized runs)
Create an .env file in apps/backend (or copy .env.example if present) with:
DATABASE_URL=postgresql://USER:PASSWORD@HOST:PORT/DB_NAME
JWT_SECRET=your_secret_here
PORT=3000
cd apps/backend
npm install
npm run dev
cd apps/frontend
npm install
npm run dev
Open the app at http://localhost:3000 and log in/register.
cd docker
docker-compose build
docker-compose up
Open http://localhost (or your Traefik domain).
Base path: /mini-crm/api
POST /auth/register— register userPOST /auth/login— login user
GET /contacts— list contacts (query:page,limit,search)GET /contacts/:id— get contactPOST /contacts— create contactPUT /contacts/:id— update contactDELETE /contacts/:id— delete contactGET /contacts/export— export contacts as CSV
GET /tags— list tagsPOST /tags— create tagDELETE /tags/:id— delete tagPOST /tags/contact/:contactId/tag/:tagId— add tag to contactDELETE /tags/contact/:contactId/tag/:tagId— remove tag from contact
- The API is mounted under
/mini-crm/apiand the frontend router under/mini-crm. - 401 responses trigger logout on the frontend.
Issues and pull requests are welcome.
MIT