Overview
UNS uses a sidecar architecture where Electron acts as the orchestrator between three layers:- React Frontend - User interface
- Electron Main Process - Browser automation and IPC
- Python Backend - Data processing and EPUB generation
Directory Structure
Core Files
main.js (Electron Main Process)
Location:/main.js (500 lines)
Responsibilities:
- Launch and manage the Python engine subprocess
- Create and manage browser windows (main UI + scraper)
- Handle IPC communication with React frontend
- Control Chromium for web scraping
- Execute JavaScript in web pages to extract content
- Manage provider scripts (load, install, delete)
- Detect and handle Cloudflare challenges
| Function | Purpose | Line |
|---|---|---|
startPythonBackend() | Spawns the Python engine process | 31 |
waitForEngine() | Polls engine health endpoint | 51 |
loadExternalProviders() | Loads provider scripts from user data | 63 |
createWindow() | Creates the main UI window | 90 |
createScraperWindow() | Creates hidden browser for scraping | 108 |
detectCloudflare() | Checks if page is Cloudflare challenge | 126 |
scrapeChapter() | Recursive scraping loop | 148 |
main.js:33-35
preload.js (IPC Bridge)
Location:/preload.js
Purpose: Exposes safe IPC methods to the React frontend via contextBridge.
API exposed to renderer:
frontend/src/App.jsx (React Router)
Location:/frontend/src/App.jsx
Purpose: Root component with routing and navigation.
Routes:
backend/api.py (Python Engine)
Location:/backend/api.py (400+ lines)
Responsibilities:
- Provide REST API for Electron to communicate with
- Store scraped chapters to disk (JSONL format)
- Track download progress
- Generate EPUB files with ebooklib
- Serve library metadata and cover images
- Manage download history
| Endpoint | Method | Purpose |
|---|---|---|
/api/health | GET | Health check for startup |
/api/save-chapter | POST | Store scraped chapter data |
/api/finalize-epub | POST | Generate EPUB from stored chapters |
/api/status/{job_id} | GET | Get download progress |
/api/history | GET | List all downloads |
/api/library | GET | List all EPUBs |
/api/cover/{filename} | GET | Extract cover image from EPUB |
/api/library/{filename} | DELETE | Delete an EPUB |
/api/stop-scrape | POST | Mark download as paused |
Data Flow
Scraping Flow
Provider System
Provider script structure:provider-example.js
- Electron scans
<userData>/providers/on startup (main.js:489) - Each
.jsfile isrequire()’d and added to theprovidersobject (main.js:76) - Frontend fetches the list via
get-providersIPC (main.js:295) - User can install new providers from URLs (main.js:327)
Key Technologies
Frontend Stack
| Technology | Purpose | Version |
|---|---|---|
| React | UI framework | 19.2 |
| React Router | Client-side routing | 7.13 |
| Vite | Build tool & dev server | 7.3 |
| Tailwind CSS | Styling | 4.2 |
| Lucide React | Icon library | 0.577 |
| ePub.js | EPUB rendering | 0.3.93 |
| React Reader | EPUB reader component | 2.0.15 |
Backend Stack
| Technology | Purpose | Version |
|---|---|---|
| FastAPI | Web framework | Latest |
| Uvicorn | ASGI server | Latest |
| ebooklib | EPUB generation | Latest |
| Pydantic | Data validation | Latest |
| PyInstaller | Compile to binary | Latest |
| Botasaurus | Web automation helpers | Latest |
Electron Stack
| Technology | Purpose | Version |
|---|---|---|
| Electron | Desktop framework | 40.7 |
| electron-builder | App packager | 26.8 |
| Axios | HTTP client | 1.13 |
| Concurrently | Run parallel commands | 9.2 |
Architecture Patterns
Sidecar Pattern
The Python engine runs as a sidecar process:- Python can be updated independently
- Browser automation stays in Electron (better detection bypassing)
- Python handles EPUB generation (better library support)
IPC Communication
Electron’s IPC is used for React ↔ Main Process communication:- React calls
window.electronAPI.method()(exposed by preload.js) - Preload.js sends IPC message to main process
- Main process performs privileged operation
- Main process sends result back via IPC
Common Workflows
Adding a New Page
Adding a New IPC Handler
Adding a Python Endpoint
Testing Strategy
Manual Testing Checklist
- App launches without errors
- All pages load (Library, Download, History, Providers)
- Can search novels from different providers
- Can start a scrape and see progress
- Can pause/resume downloads
- EPUBs appear in library after completion
- Can open EPUBs in the built-in reader
- Can install/delete providers
- Cloudflare bypass works (if enabled)
Debugging Tips
Frontend issues:- Open DevTools: Cmd/Ctrl + Shift + I
- Check Console for React errors
- Use React DevTools extension
- Check terminal output where
npm run devis running - Add
console.log()in main.js - Use
console.error()for Python engine errors
- Test the binary directly:
./backend/dist/engine /tmp/test - Check
pythonProcess.stderrlogs in main.js:48 - Add print statements in api.py (they’ll appear in main.js logs)
- Delete
node_modules/,frontend/node_modules/,backend/venv/ - Reinstall all dependencies
- Rebuild Python engine from scratch
- Clear electron-builder cache:
rm -rf ~/Library/Caches/electron-builder/
Next Steps
Development Setup
Set up your development environment
Building for Production
Package the app for distribution
