Skip to content

Introduce Electron-based webui#1590

Open
BitcrushedHeart wants to merge 2 commits into
Nerogar:masterfrom
BitcrushedHeart:Webui
Open

Introduce Electron-based webui#1590
BitcrushedHeart wants to merge 2 commits into
Nerogar:masterfrom
BitcrushedHeart:Webui

Conversation

@BitcrushedHeart

Copy link
Copy Markdown
Contributor

Summary

Adds an Electron + React desktop frontend (OneTrainerWeb) as an alternative to the customtkinter GUI, backed by a FastAPI bridge in web/backend that talks to the existing training backend through the current TrainCallbacks/TrainCommands interface. No changes to modules/, scripts/, or training_presets/, so the existing GUI and CLI training path are unaffected.

What's included:

  • web/backend: FastAPI app with routers for config, presets, concepts, samples, sampling, training, tools (dataset/caption/video utilities), model conversion, tensorboard, wiki, secrets, and system/GPU info, plus WebSocket handlers for training progress, system metrics, and a terminal.
  • web/gui: Electron main process (spawns the FastAPI server, manages the window, splash screen) and a React + Vite + Tailwind renderer covering the same tabs as the desktop UI (general, model, training, LoRA, embedding, concepts, sampling, tools, performance, etc.).
  • web/scripts: generators that introspect modules/util/config and modules/util/enum to produce TypeScript types and UI schemas, so the web UI's parameter set stays in sync with the Python config classes instead of being hand-maintained.
  • Root-level start-web-ui.bat / start-web-ui.sh and an install step to build and launch the new frontend, plus a CI workflow to lint it.

I've been running this on my own fork for months and have exercised most of the functionality end to end (training runs across several model types, config load/save, sampling, tools).

Test plan

  • pre-commit run --all-files passes
  • Launched the affected UI or script and exercised the change
  • Tested with at least one real preset / config when relevant (note which: used across multiple presets/model types over months of daily use on my fork)

Manual testing: used this webui as my daily driver for training on my experimental fork for several months, covering most of the app's functionality (config editing, concepts, sampling, tools, training runs) end to end.

AI assistance

  • AI-assisted — I have read every line in this diff and can defend each change

Add an Electron + React (Vite/Tailwind) desktop frontend and a FastAPI
bridge in web/, giving OneTrainer a modern GUI alongside the existing
customtkinter UI without touching the training backend.

- web/backend: FastAPI app with routers for config, presets, concepts,
  samples, sampling, training, tools (dataset/video/caption utilities),
  converter, tensorboard, wiki, secrets, system/GPU info and mask editor,
  plus WebSocket handlers for training/system/terminal streams.
- web/gui: Electron main process, preload/IPC bridge, splash screen, and
  a React renderer with pages mirroring the desktop UI's tabs
  (general/model/training/lora/embedding/tools/performance/etc.),
  Tailwind styling, and generated TypeScript types/schemas mirrored from
  the Python config and enum classes.
- web/scripts: generators that introspect modules/util/config and
  modules/util/enum to emit TypeScript types, UI schemas, and metadata,
  plus a hardcoded-option checker and ESLint runner, keeping the web UI
  in sync with the Python source of truth.
- Root-level start-web-ui.bat/.sh, install.bat, and CI lint workflow to
  build/launch the new frontend and lint it in CI.
- Bug fixes folded in: path traversal hardening in path_security.py,
  timestep distribution correctness, performance page and system
  websocket fixes, safer yt-dlp invocation (video_service.py), and an
  eslint globals fix for Node-context scripts.
Dead code (grep-verified, pure deletion):
- Delete unused useArrayField hook and Skeleton component
- Remove dead configStore/uiSchemaStore/trainingStore methods and
  configApi.getSchema
- Strip unused ErrorBoundary fallback/fallbackRender/onReset props
- Prune 13 unused brandColors constants

De-duplication (behavior-preserving):
- Parametrize ScalarChart and delete PerformancePage's near-verbatim
  MetricChart copy
- Extract shared SampleParamsForm from Manual/Standalone sampling modals
- Factor VideoToolModal's twin extract tabs into a shared hook + scaffold
- Extract hardenWindow/loadRenderer helpers in Electron main

Replace 276-line hand-rolled markdown parser with marked + existing
DOMPurify sanitizer.

Net: 640 fewer source lines. Typecheck, ESLint (strict), and production
build all pass.

Claude-Session: https://claude.ai/code/session_018zFRV8uwTfLT4krm3zwVDz
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant