# How Settings Are Managed and Accessed in the Modly Application

> Learn how Modly manages and accesses settings securely. Discover how configuration paths and tokens are stored in a JSON file and accessed via pure functions and IPC handlers.

- Repository: [lightningpixel/modly](https://github.com/lightningpixel/modly)
- Tags: internals
- Published: 2026-08-19

---

**Modly stores configuration paths and tokens in a JSON file inside Electron’s user-data directory, exposing them via pure functions (`getSettings`, `setSettings`) and IPC handlers for secure cross-process access.**

The `lightningpixel/modly` repository implements a centralized configuration system for its Electron-based AI image generation workflow. Understanding how settings are managed and accessed in the Modly application reveals a robust pattern that separates storage logic from business concerns while maintaining synchronization between the main process, renderer, and Python backend.

## Central Settings Store

The foundation of Modly’s configuration system resides in [`electron/main/settings-store.ts`](https://github.com/lightningpixel/modly/blob/main/electron/main/settings-store.ts), which defines the data structures and persistence logic.

### The AppSettings Interface and Defaults

The module exports an `AppSettings` interface that type-safely declares configurable paths for **models**, **workspace**, **workflows**, **extensions**, and **dependencies**, plus optional values like the Hugging Face token. The store generates default directory values dynamically using Electron’s `app.getPath('userData')`, ensuring platform-appropriate locations across Windows, macOS, and Linux.

### Reading and Writing Configuration

Two pure functions handle all disk access:

- **`getSettings(userData: string): AppSettings`** – Reads [`settings.json`](https://github.com/lightningpixel/modly/blob/main/settings.json) from the user-data directory if it exists, merges persisted values with defaults, and safely migrates legacy keys (specifically converting `outputsDir` to `workspaceDir`).
- **`setSettings(userData: string, patch: Partial<AppSettings>): AppSettings`** – Writes the updated JSON back to disk and returns the complete new settings object.

The actual file location is determined by `settingsPath(userData)`, which simply joins the user-data folder with [`settings.json`](https://github.com/lightningpixel/modly/blob/main/settings.json).

## IPC Exposure for Cross-Process Access

Since Electron’s renderer process cannot directly access the filesystem, Modly exposes settings through secure IPC channels defined in [`electron/main/ipc-handlers.ts`](https://github.com/lightningpixel/modly/blob/main/electron/main/ipc-handlers.ts).

### Registering IPC Handlers

The main process registers two handlers during initialization:

```typescript
ipcMain.handle('settings:get', () => getSettings(app.getPath('userData')));

ipcMain.handle('settings:set', async (_event, patch) => {
  const updated = setSettings(app.getPath('userData'), patch);
  // Synchronize environment variables when HF token changes
  return updated;
});

```

These endpoints allow the UI to request current configuration or persist partial updates without knowing the underlying file path.

### Renderer Process Usage

React components in the renderer invoke these handlers through the preload script:

```typescript
// Retrieve current configuration
const settings = await window.ipc.invoke('settings:get');
console.log(settings.modelsDir, settings.workspaceDir);

// Update a specific path
await window.ipc.invoke('settings:set', {
  workspaceDir: '/custom/path/to/workspace',
});

```

## Consuming Settings Throughout the Application

Core modules running in the main process import `getSettings` directly to obtain directory locations or authentication tokens, ensuring they always read the latest on-disk values.

### Python Environment Setup

In [`electron/main/python-setup.ts`](https://github.com/lightningpixel/modly/blob/main/electron/main/python-setup.ts), the virtual environment path is constructed by joining the `dependenciesDir` from settings with `'venv'`:

```typescript
import { getSettings } from './settings-store';
import { join } from 'path';

const venvPath = join(
  getSettings(userData).dependenciesDir, 
  'venv'
);

```

### Model Download Authentication

[`electron/main/model-downloader.ts`](https://github.com/lightningpixel/modly/blob/main/electron/main/model-downloader.ts) and [`electron/main/python-bridge.ts`](https://github.com/lightningpixel/modly/blob/main/electron/main/python-bridge.ts) both access `getSettings(userData).hfToken` to authenticate Hugging Face downloads. The token is passed to download routines or exposed to Python subprocesses via environment variables.

### Workspace and Extension Management

Various IPC handlers—handling model lists, exports, workspace utilities, and extension installation—resolve their target directories by calling `getSettings(app.getPath('userData'))` and accessing the specific path properties (`.modelsDir`, `.extensionsDir`, etc.).

## Runtime Synchronization and Safety

Modly implements additional safeguards and synchronization mechanisms beyond simple file storage.

### HF Token Propagation

When the Hugging Face token changes via the `settings:set` IPC handler, the system immediately updates `process.env['HF_TOKEN']` and notifies the FastAPI backend through a POST request to `/settings/hf-token`. This guarantees that child processes spawned after the change inherit the new token without requiring an application restart.

### Filesystem Security Validation

The `fs:deleteDirectory` IPC handler validates deletion requests against a whitelist of allowed roots derived from the current settings (models, workspace, extensions, and cache directories). This prevents the application from accidentally or maliciously manipulating arbitrary filesystem locations outside its managed scope.

## Summary

- **Storage**: All settings live in a JSON file inside Electron’s `userData` directory, managed by deterministic functions in [`electron/main/settings-store.ts`](https://github.com/lightningpixel/modly/blob/main/electron/main/settings-store.ts).
- **Access**: The renderer communicates via IPC (`settings:get`, `settings:set`) while main-process modules import `getSettings` directly.
- **Synchronization**: HF token changes propagate immediately to environment variables and the FastAPI server.
- **Security**: Filesystem operations validate paths against whitelist roots defined in the current settings.

## Frequently Asked Questions

### Where does Modly store its configuration file?

Modly stores configuration in [`settings.json`](https://github.com/lightningpixel/modly/blob/main/settings.json) inside Electron’s `userData` directory (typically `%APPDATA%/Modly` on Windows, `~/Library/Application Support/Modly` on macOS, or `~/.config/Modly` on Linux). The exact path is computed at runtime by joining `app.getPath('userData')` with [`settings.json`](https://github.com/lightningpixel/modly/blob/main/settings.json).

### How does Modly handle changes to the Hugging Face token?

When updated via IPC, the `settings:set` handler immediately writes the token to disk, updates `process.env['HF_TOKEN']`, and sends a notification to the FastAPI server at `/settings/hf-token`. This ensures both the current process and any subsequently spawned Python subprocesses use the updated authentication credentials.

### Can the renderer process directly access the settings file?

No. The renderer process must use IPC invocations (`window.ipc.invoke('settings:get')` and `window.ipc.invoke('settings:set')`) to interact with configuration. This isolation prevents the UI from accessing sensitive filesystem locations directly and ensures all changes pass through validation logic in the main process.

### How does Modly prevent deletion of arbitrary directories?

The `fs:deleteDirectory` IPC handler validates requested paths against a whitelist of allowed roots derived from the current `AppSettings` (models, workspace, extensions, and cache directories). The operation only proceeds if the target path resolves within one of these authorized locations.