Vue 3 frontend application for browsing and reading manga with a clean, responsive interface.
- Framework: Vue 3 (Composition API)
- Build Tool: Vite 7
- Language: TypeScript
- Styling: Tailwind CSS 3
- Router: Vue Router 4
- UI Components: Radix UI (via reka-ui)
- Icons: Lucide Vue Next
- HTTP Client: Axios
frontend/
├── src/
│ ├── api/
│ │ └── index.ts # API client & types
│ ├── components/
│ │ ├── ui/ # Reusable UI components
│ │ ├── reader/ # Reader-specific components
│ │ ├── pagination/ # Pagination component
│ │ ├── Logo.vue
│ │ └── ThemeToggle.vue
│ ├── views/
│ │ ├── Home.vue # Library & scan page
│ │ ├── MangaReader.vue # Reading interface
│ │ ├── History.vue # Reading history
│ │ └── Bookmarks.vue # Saved bookmarks
│ ├── lib/
│ │ └── utils.ts # Utility functions
│ ├── App.vue # Root component
│ ├── main.ts # Application entry
│ └── style.css # Global styles
├── public/ # Static assets
├── components.json # UI components config
├── tailwind.config.js # Tailwind configuration
├── vite.config.ts # Vite configuration
└── package.json
-
Home (
/)- Manga library grid view
- Directory scanning
- Recently read manga section
-
Manga Reader (
/manga/:id)- Chapter selection
- Page-by-page reading
- Keyboard navigation (arrow keys)
- Progress tracking
- Bookmark creation
-
History (
/history)- Reading history timeline
- Jump back to last read page
- Clear history
-
Bookmarks (
/bookmarks)- Saved page bookmarks
- Notes on bookmarks
- Quick navigation to bookmarked pages
- Button - Various button styles
- Card - Content containers
- Input - Form inputs
- Select - Dropdown selects
- Tooltip - Hover tooltips
- Sonner - Toast notifications
- Pagination - Page navigation
- Light/Dark mode support
- Toggle via ThemeToggle component
- Persisted to localStorage
- Node.js 24+
- npm
-
Install dependencies
npm install
-
Run development server
npm run dev
Development server runs on http://localhost:5173
The app will proxy API requests to http://localhost:3000
npm run dev- Start dev server with hot reloadnpm run build- Build for productionnpm run preview- Preview production build
The frontend communicates with the backend via REST API.
import { api } from '@/api'
// Get all manga
const manga = await api.getManga()
// Scan directory
const result = await api.scanDirectory('/manga')
// Get chapters
const chapters = await api.getChapters(mangaId)
// Get pages
const pages = await api.getPages(mangaId, chapterPath)
// Reading history
const history = await api.getHistory()
await api.createHistory({ mangaId, chapterPath, pageNumber })
// Bookmarks
const bookmarks = await api.getBookmarks()
await api.createBookmark({ mangaId, chapterPath, pageNumber, note })
// Progress
const progress = await api.getProgress(mangaId)
await api.updateProgress({ mangaId, chapterPath, pageNumber })The app uses Tailwind CSS with a custom configuration:
- Custom color palette (primary, secondary, accent, muted, etc.)
- Dark mode support
- Custom animations
- Responsive breakpoints
Theme colors are defined using CSS variables in src/style.css:
:root {
--background: 0 0% 100%;
--foreground: 20 14.3% 4.1%;
--primary: 24 9.8% 10%;
/* ... */
}
.dark {
--background: 20 14.3% 4.1%;
--foreground: 60 9.1% 97.8%;
/* ... */
}The frontend is built as a static site and served by the backend.
- Dependencies are installed
- Vite builds the production bundle
- Output is placed in
/app/dist - Backend serves the static files
- Base image:
node:24-alpine - Build output:
/app/dist - Served by backend on port 3000
vue- Frameworkvue-router- Routingaxios- HTTP client@vueuse/core- Vue utilitiesreka-ui- UI componentslucide-vue-next- Iconsvue-sonner- Toast notificationstailwindcss- Stylingclass-variance-authority- Component variantsclsx&tailwind-merge- Class utilities
vite- Build tool@vitejs/plugin-vue- Vue plugin for Vitetypescript- TypeScript compilervue-tsc- Vue TypeScript checkertailwindcss- CSS frameworkpostcss&autoprefixer- CSS processing
The frontend uses ports configured in the project's .env file:
FRONTEND_PORT(default: 5173) - Dev server portBACKEND_PORT(default: 3000) - Backend API port for proxy
The Vite dev server automatically proxies /api requests to the backend. In production, the frontend is built as static files and served by the backend.
- All images are lazy-loaded for better performance
- Keyboard navigation is supported in the reader (arrow keys)
- Reading progress is auto-saved
- Theme preference is saved to localStorage
- Responsive design works on mobile, tablet, and desktop