This page documents the web application implementation of Prompt Optimizer, specifically covering the @prompt-optimizer/web package. This includes the Vite build configuration, single-page application (SPA) architecture, client-side routing, IndexedDB persistence via Dexie.js, and browser-specific constraints such as CORS limitations.
For information about the desktop application implementation that bypasses CORS restrictions, see Desktop Application. For browser extension implementation, see Browser Extension. For Docker and Vercel deployment configurations, see Docker Deployment and Vercel Deployment.
The web application follows a minimal shell pattern where the @prompt-optimizer/web package serves as a thin entry point that imports and renders the shared @prompt-optimizer/ui package. All business logic resides in @prompt-optimizer/core, and all UI components and application logic reside in @prompt-optimizer/ui.
Sources: packages/web/src/App.vue1-26 packages/ui/src/index.ts1-254 packages/web/package.json1-36
The web application's entry point is minimal, delegating all functionality to the shared UI package.
The App.vue component serves as a thin wrapper that renders PromptOptimizerApp:
Key characteristics:
@prompt-optimizer/ui@prompt-optimizer/coreThis architecture ensures code reuse across web, desktop, and extension platforms while allowing platform-specific customization at the bootstrap level.
The web application bootstrap sequence follows this flow:
Sources: packages/web/src/App.vue1-26 packages/ui/src/index.ts113-116
The web application uses Vite as its build tool, configured for both development and production environments.
| Script | Command | Purpose |
|---|---|---|
dev | vite --force | Start development server with HMR, force cache rebuild |
build | vite build | Production build with minification and tree-shaking |
preview | vite preview | Preview production build locally |
test | vitest | Run unit tests in watch mode |
Development Mode:
Production Mode:
assets/index-[hash].js)Environment-Specific Configuration:
The build can be configured for Electron by setting ELECTRON_BUILD=true:
packages/desktop/package.json12
This adjusts the base path to ./ for Electron's file:// protocol.
Sources: packages/web/package.json6-13 packages/desktop/package.json12
The web application uses Vue Router for client-side routing, with routes defined in the @prompt-optimizer/ui package.
Route Configuration:
The router is created in the UI package and exported for application-level installation. All workspace components are lazy-loaded to reduce initial bundle size:
When a user switches modes or sub-modes, the application updates the route and renders the corresponding workspace component:
Sources: packages/ui/src/index.ts116 packages/ui/src/components/OptimizationModeSelector.vue1-124
The web application uses IndexedDB for client-side data persistence, accessed through the Dexie.js library via DexieStorageProvider.
The DexieStorageProvider implements the IStorageProvider interface, providing CRUD operations for all persisted data:
| Method | Purpose | Object Store |
|---|---|---|
getTextModels() | Retrieve user-defined model configurations | text_models |
saveTextModels(models) | Save model configurations | text_models |
getTemplates() | Retrieve custom templates | templates |
saveTemplates(templates) | Save templates | templates |
getHistory() | Retrieve optimization history chains | history |
saveHistory(chains) | Save history chains | history |
getPreference(key) | Retrieve user preference | preferences |
setPreference(key, value) | Save user preference | preferences |
getContexts() | Retrieve context packages | contexts |
saveContexts(contexts) | Save context packages | contexts |
Database Schema:
The Dexie database schema is defined with version migrations:
Browser Storage Limits:
| Browser | Quota Type | Typical Limit |
|---|---|---|
| Chrome | Best-effort | ~60% of disk space (shared) |
| Firefox | Best-effort | ~10-50% of disk space (shared) |
| Safari | Best-effort | ~1GB |
| Edge | Best-effort | ~60% of disk space (shared) |
Graceful Degradation:
When storage quota is exceeded, the application:
QuotaExceededError exceptionsSources: packages/core/package.json38 packages/ui/src/index.ts163-165
The web application is subject to Cross-Origin Resource Sharing (CORS) policies enforced by browsers, which can prevent access to certain LLM APIs.
The application detects CORS errors and displays appropriate warnings:
ModelManager CORS Warning:
packages/ui/src/components/ModelManager.vue displays a warning badge when a model's API endpoint is detected to have CORS issues:
Warning Message:
⚠️ This model may have CORS restrictions in the web version. Consider using the desktop application for full access.
Option 1: Use Desktop Application
The Electron-based desktop application bypasses CORS restrictions by running core services in the Node.js main process. See Desktop Application for details.
Option 2: Use CORS Proxy
Users can configure a CORS proxy service as an intermediary:
Option 3: Configure Local API with CORS Headers
For Ollama and similar local services, users can configure CORS headers:
Option 4: Use Docker Deployment
The Docker deployment includes an Nginx reverse proxy that can handle CORS. See Docker Deployment.
Sources: packages/ui/src/components/ModelManager.vue
The web application supports environment-based configuration via .env files processed by Vite.
| Variable | Purpose | Default | Example |
|---|---|---|---|
VITE_OPENAI_API_KEY | Pre-configure OpenAI API key | None | sk-... |
VITE_GEMINI_API_KEY | Pre-configure Gemini API key | None | AIza... |
VITE_ANTHROPIC_API_KEY | Pre-configure Anthropic API key | None | sk-ant-... |
VITE_CUSTOM_API_URL_* | Define custom API endpoint | None | http://localhost:11434 |
VITE_CUSTOM_API_KEY_* | Custom API authentication | None | custom-key |
VITE_CUSTOM_API_NAME_* | Custom API display name | None | Local Ollama |
Configuration Flow:
.env files and injects values as import.meta.env.VITE_*ModelManagerUIModelManagerExample .env:
Sources: packages/web/package.json28
1. Install Dependencies:
2. Start Development Server:
This starts Vite dev server with:
5173 (default)3. Development Checklist:
| Task | Status | Notes |
|---|---|---|
| Core services built | ✓ | Auto-built by pnpm dev |
| UI package built | ✓ | Auto-built by pnpm dev |
| IndexedDB accessible | ✓ | Available in browser DevTools → Application |
| CORS errors | ⚠️ | Expected for localhost APIs |
Production Build:
Output Structure:
packages/web/dist/
├── index.html # Entry HTML
├── assets/
│ ├── index-[hash].js # Main bundle
│ ├── index-[hash].css # Styles
│ ├── BasicSystemWorkspace-[hash].js # Lazy-loaded chunk
│ ├── ContextSystemWorkspace-[hash].js
│ └── ... # Other lazy-loaded chunks
└── favicon.ico
Unit Tests:
E2E Tests (from workspace root):
The E2E tests use Playwright and VCR (Video Cassette Recorder) mode to replay pre-recorded API responses, avoiding real API calls during testing.
Sources: packages/web/package.json6-14 package.json27-32
Code Splitting:
The application uses route-based code splitting to reduce initial load time:
| Chunk | Size (approx) | Load Trigger |
|---|---|---|
| Main bundle | ~200KB | Initial load |
| BasicSystemWorkspace | ~50KB | Route: /basic/system |
| ContextSystemWorkspace | ~80KB | Route: /context/system |
| UI components (shared) | ~150KB | Initial load |
| Core services | ~100KB | Initial load |
Tree Shaking:
Unused exports from @prompt-optimizer/ui and @prompt-optimizer/core are eliminated during production builds.
IndexedDB Access:
All IndexedDB operations are asynchronous and non-blocking:
Streaming LLM Responses:
The web application supports streaming API responses to provide real-time feedback:
Sources: packages/web/package.json1-36
After running pnpm build, the packages/web/dist/ directory contains all static assets ready for deployment:
File Structure:
dist/
├── index.html # SPA entry point
├── assets/
│ ├── *.js # JavaScript bundles
│ ├── *.css # Stylesheets
│ └── *.woff2 # Font files
└── favicon.ico
Vercel (Recommended):
See Vercel Deployment for one-click deployment configuration.
Docker:
The web build is packaged with Nginx in the Docker image. See Docker Deployment.
Static Hosting:
The output can be served from any static file host:
Server Requirements:
index.html (SPA routing)Sources: packages/web/package.json8 package.json16
| Feature | Web | Desktop | Extension |
|---|---|---|---|
| Runtime | Browser | Electron | Browser |
| Storage | IndexedDB | JSON Files | chrome.storage.local |
| CORS | ❌ Restricted | ✅ Bypassed | ⚠️ Partially restricted |
| File Access | ❌ No | ✅ Yes | ❌ No |
| Install | None (URL) | Download installer | Chrome Web Store |
| Updates | Automatic | Manual/Auto-update | Automatic |
| Offline | ⚠️ Limited | ✅ Full | ⚠️ Limited |
| API Keys | User-provided | User-provided | User-provided |
Use Case Recommendations:
Sources: packages/web/package.json1-36 packages/desktop/package.json1-99 packages/extension/package.json1-37
Refresh this wiki