4.3 KiB
Zui
Node-based editor (React Flow) for configs, variables, and rendering (PlantUML, Markdown, etc.). Optional Node.js backend API for demos or future features (e.g. todos CRUD).
Project layout
my-app/
├── frontend/ # React app (Vite, TypeScript)
│ ├── Dockerfile # Multi-stage for prod (build → Nginx)
│ ├── Dockerfile.dev # Dev with hot reload
│ ├── src/
│ ├── public/
│ ├── nginx.conf
│ └── package.json
├── backend/ # Node.js/Express API
│ ├── Dockerfile
│ ├── src/
│ │ └── index.js
│ └── package.json
├── docker-compose.yml
├── .dockerignore
└── .gitignore
Ignored by git: node_modules, dist, .env, .env.* (see .gitignore). Local Docker overrides: docker-compose.override.yml (optional, not committed).
Run locally (dev)
Frontend only:
cd frontend && npm install && npm run dev
# → http://localhost:3000
Frontend + backend (so the app can show “Backend API: N todos”):
# Terminal 1 – backend
cd backend && npm install && npm run dev
# → http://localhost:8080
# Terminal 2 – frontend
cd frontend && npm install && npm run dev
# → http://localhost:3000 (Vite proxies /api/todos to backend)
Run with Docker
docker compose up --build
- Frontend: http://localhost:3000 (Nginx;
/api/*proxied to backend). - Backend: http://localhost:8080 (Express).
Environment variables (backend service):
| Variable | Default | Description |
|---|---|---|
PORT |
8080 |
Backend listen port. |
CORS_ORIGIN |
http://localhost:3000 |
Allowed origin for CORS. |
For self-hosting (e.g. Tailscale/HTTPS): set CORS_ORIGIN to your frontend URL; put Caddy or Nginx in front for TLS if needed.
Dev with Docker (frontend hot reload): use frontend/Dockerfile.dev and mount ./frontend as a volume, or run cd frontend && npm run dev locally.
Scripts
| Command | Description |
|---|---|
cd frontend && npm run dev |
Vite dev server. |
cd frontend && npm run build |
Build frontend for production. |
cd frontend && npm run preview |
Preview production build. |
cd backend && npm run dev |
Backend with --watch. |
cd backend && npm start |
Backend production run. |
docker compose up --build |
Run frontend + backend in Docker. |
Backend API (no DB)
| Method | Path | Description |
|---|---|---|
| GET | /api/todos |
List all todos. |
| GET | /api/todos/:id |
Get one todo. |
| POST | /api/todos |
Create ({ "title": "...", "completed": false }). |
| PUT | /api/todos/:id |
Update. |
| DELETE | /api/todos/:id |
Delete. |
| GET | /health |
Health check (e.g. for Docker). |
| POST | /api/agent |
Run AI agent; body { "prompt", "context?", "contextNodes?" } → { "markdown" }. |
Data is in-memory (resets on restart). Add a JSON file or DB later if needed.
Agent node (local LLM or OpenAI)
The Agent node uses an OpenAI-compatible API. You can use:
1. Local LLM (e.g. LM Studio)
-
Install LM Studio and load a model.
-
Start the local server: in LM Studio open the Developer tab and run the Local Server (default:
http://localhost:1234). -
In the project root or
backend/, set:export AI_BASE_URL=http://localhost:1234/v1 # Optional: set to the model name shown in LM Studio (e.g. the loaded model id). Default is "local-model". export AI_MODEL=your-model-name -
Start the backend (
cd backend && npm run dev). The Agent node will use your local model.
2. OpenAI
Set OPENAI_API_KEY to your API key. The backend will use gpt-4o-mini unless you set AI_MODEL.
Env summary (backend)
| Variable | When to use | Description |
|---|---|---|
AI_BASE_URL |
Local LLM (LM Studio, Ollama, etc.) | OpenAI-compatible base URL, e.g. http://localhost:1234/v1. |
AI_MODEL |
Optional | Model id (for local: use the name shown in LM Studio; for OpenAI: e.g. gpt-4o-mini). |
OPENAI_API_KEY |
OpenAI only | Your OpenAI API key. Not required when using AI_BASE_URL only. |