Build a web-based dictionary application called Owl that supports MDX/MDD dictionary files.
The app allows users to look up words and manage their own personal dictionaries.
Core dictionary engine: Go library github.com/lib-x/mdx (MDX/MDD parser with io/fs.FS support).
- MDX files: text dictionary entries (definitions, HTML content)
- MDD files: associated resources (images, audio, CSS, fonts) paired with MDX
- When a user uploads an MDX, they should also be able to upload the paired MDD file(s)
- Backend must serve MDD resources so frontend can render embedded images/audio in definitions
- Backend: Go (REST API)
- Frontend: Modern web UI (React with Vite, or Vue with Vite — choose one and be consistent)
- Database: SQLite (for user accounts, dictionary metadata)
- Deployment: Docker + docker-compose (single
docker-compose upto run everything)
owl/
├── backend/
│ ├── cmd/
│ │ └── server/main.go # Entry point
│ ├── internal/
│ │ ├── api/ # HTTP handlers, routes
│ │ ├── dictionary/ # MDX loading, querying logic
│ │ ├── user/ # User auth (simple JWT or session)
│ │ └── models/ # Data models
│ ├── data/ # SQLite DB, uploaded MDX files
│ ├── go.mod
│ ├── go.sum
│ └── Dockerfile
├── frontend/
│ ├── src/
│ │ ├── components/ # UI components
│ │ ├── pages/ # Home, Search, DictionaryManager
│ │ ├── services/ # API client
│ │ ├── App.tsx (or App.vue)
│ │ └── main.tsx (or main.ts)
│ ├── package.json
│ ├── vite.config.ts
│ ├── Dockerfile
│ └── nginx.conf # For production serving
├── docker-compose.yml
├── TASK.md # This file
└── README.md
- Search bar on homepage, type a word and get definitions
- Support fuzzy/prefix matching (not just exact match)
- Show results from ALL loaded dictionaries, grouped by dictionary name
- HTML rendering of dictionary entries (MDX content is HTML)
- Upload MDX files (and optionally paired MDD resource files) via web UI
- List uploaded dictionaries with metadata (title, description, entry count)
- Enable/disable individual dictionaries
- Delete dictionaries
- Store uploaded files in a persistent volume
- Simple registration/login (username + password, bcrypt hashed)
- JWT token auth for API
- Each user has their own set of dictionaries (isolated)
- Admin user can see all dictionaries
docker-compose.ymlwith backend + frontend + volumes- Backend listens on port 8080
- Frontend served by nginx on port 3000 (or proxied through backend)
- Persistent volume for: SQLite DB, uploaded MDX files
.envfile for configuration (JWT secret, ports, etc.)
POST /api/auth/register # Register
POST /api/auth/login # Login, returns JWT
GET /api/dictionaries # List user's dictionaries
POST /api/dictionaries/upload # Upload MDX (+ optional MDD) file(s)
DELETE /api/dictionaries/:id # Delete a dictionary
PATCH /api/dictionaries/:id # Toggle enable/disable
GET /api/search?q=word # Search across enabled dictionaries
GET /api/search?q=word&dict=id # Search in specific dictionary
import "github.com/lib-x/mdx"
// Load MDX dictionary
mdict, err := mdx.New("path/to/dict.mdx")
err = mdict.BuildIndex()
// Load paired MDD resource file (same name, .mdd extension)
// MDD files share the same base name as MDX, e.g. oald.mdx + oald.mdd
// Query word definition (returns HTML string)
definition, err := mdict.Lookup("hello")
// Dictionary metadata
title := mdict.Title()
desc := mdict.Description()
// FS interface — serve MDD resources (images, audio, CSS) via HTTP
// This is key: mdict.FS() returns an io/fs.FS for the MDD content
// Mount it at /api/dictionaries/:id/resource/ to serve embedded assets
fs := mdict.FS()
data, err := fs.Open("img/hello.png")- Each dictionary's MDD resources should be accessible via HTTP
- Route:
GET /api/dictionaries/:id/resource/*filepath - The backend uses
mdict.FS()to serve files from the MDD archive - Frontend dictionary HTML may reference images like
<img src="img/word.png">— rewrite these to point to the resource endpoint
- Clean, modern design (use Tailwind CSS or similar)
- Dark/light mode toggle
- Responsive (mobile-friendly)
- Search results display with dictionary source labels
- Drag-and-drop file upload for MDX files
- Loading states and error handling
- All Go code must pass
go vetandgolangci-lint(if available) - Frontend must build without errors
- Docker build must succeed
- Include a README.md with setup instructions
- Initialize Go module and install lib-x/mdx dependency
- Create backend: models, database layer (SQLite), dictionary service
- Create backend: API routes, auth middleware, handlers
- Initialize frontend project with Vite
- Build frontend pages: Login, Search, Dictionary Manager
- Connect frontend to backend API
- Create Dockerfiles for both services
- Create docker-compose.yml
- Test end-to-end: build, run, verify search works
- Write README.md
- This is an ARM64 (aarch64) Linux system
- Use Go 1.21+ features
- Keep dependencies minimal
- Chinese dictionary content should render correctly (UTF-8 everywhere)