Web UI Overview¶
Open a terminal and run photoprism start (or make start inside the main repository) to bring up the built-in web server on http://localhost:2342. The development compose file (compose.yaml) exposes the same port, so once the backend is reachable you can iterate on the frontend without rebuilding the entire container stack.
Frameworks and Bundling¶
- The UI is a Vue 3 + Vuetify 4 single-page application. Bootstrap and other legacy frameworks are no longer used.
- The entry points live in
frontend/src/app.js(bootstrap logic, router, plugins) andfrontend/src/app.vue(layout shell). The route definitions are stored infrontend/src/app/routes.js. - Vite (configured in
frontend/vite.config.mjs, with plugins infrontend/vite.plugins.mjs) bundles the Vue code, generates the service worker for production builds, and emits the optimized JS/CSS that gets injected into the Go HTML template atassets/templates/index.gohtml. - Startup logic such as the browser capability check and splash screen is implemented in
assets/static/js/browser-check.jsandfrontend/src/css/splash.css, so update both files together when changing the loader. - Documentation and landing pages may use lightweight static tooling (for example MkDocs Material or Hugo), but the actual app always goes through the Vue stack described above.
For a detailed tour of every directory see frontend/CODEMAP.md in the main repository.
Components¶
Reusable Vue components live under frontend/src/component/, while top-level pages that map to Vue Router routes are stored in frontend/src/page/. Global component registration happens in frontend/src/component/components.js. The UI Components page explains how we group and reference shared widgets, while Vuetify’s own component catalog covers the standard building blocks that ship with the framework.
Dependencies¶
- The authoritative dependency list is
frontend/package.json. - The frontend is an npm workspace of the repository root, so
node_modules/andpackage-lock.jsonlive at the root. Install or refresh dependencies from the root withmake dep-js, which runsnpm ci;make depalso downloads the models. - Add a dependency with
npm install --ignore-scripts --workspace frontend <package>from the repository root, so it is recorded infrontend/package.jsonand the rootpackage-lock.json. Always checkfrontend/CODEMAP.mdbefore adding new runtime libraries.
Build, Watch, and Test¶
- Development server / watcher:
make watch-jsfrom the repo root, orcd frontend && npm run watch. This rebuilds the bundle whenever you change files underfrontend/src/. - Production build:
make build-js(root) orcd frontend && npm run build. - Dev build without watcher:
npm run build-dev. - Unit tests (Vitest):
make vitest-watch/make vitest-coverageorcd frontend && npm run test. - Linting & formatting:
npm run lintandnpm run fmtkeep ESLint + Prettier aligned with CI.
External Resources¶
- https://vuejs.org/guide/quick-start.html — official Vue 3 guide
- https://vuetifyjs.com/en/getting-started/installation/ — Vuetify docs and Material Design guidance
- https://web.dev/explore/progressive-web-apps/ — Google’s canonical PWA reference
- https://vite.dev/guide/ — bundler used in
frontend/vite.config.mjs - https://web.dev/articles/fullscreen/ — background reading for fullscreen helpers in
frontend/src/common/fullscreen.js - https://maplibre.org/ — base engine for Places maps (see maps.md)
- https://floating-ui.com/ / https://floating-vue.starpad.dev/ — tooltip stack we rely on for hover/focus hints
Older Vue 2 tutorials can still provide inspiration, but always cross-check APIs with the current Vue 3 / Vuetify 4 documentation before copying snippets into the codebase.