# Where Is the Electron-Free Service Core Located in the Nodeterm Codebase?

> Discover the Electron-free service core location in the nodeterm codebase. Find platform-agnostic logic in src/core while Electron code stays in src/main and src/preload.

- Repository: [eneskirca/nodeterm](https://github.com/eneskirca/nodeterm)
- Tags: internals
- Published: 2026-08-26

---

**The Electron-free service core of nodeterm resides in the `src/core/` directory, containing all platform-agnostic business logic while Electron-specific code remains isolated in `src/main/` and `src/preload/`.**

The nodeterm terminal emulator separates its cross-platform logic from desktop framework dependencies to support both an Electron-based GUI and a headless Server Edition. This architectural decision places the **Electron-free service core** under `src/core/`, enabling the application to run on standard Node.js APIs without importing Electron modules. According to the nodeterm source code, the core handles everything from PTY management to Git operations, communicating with its host through an abstract platform interface.

## Location and Architecture of the Core Services

The **Electron-free service core** is deliberately confined to the `src/core/` directory tree. This folder contains zero Electron imports, depending solely on standard Node.js APIs and abstract interfaces.

- **`src/core/`** – Platform-agnostic business logic (PTY, workspace storage, Git, agents)
- **`src/main/`** – Electron main process implementations (host-specific)
- **`src/preload/`** – Electron preload scripts and context bridges
- **`src/shared/`** – Utilities used by both core and Electron layers (IPC definitions, SSH helpers)

This separation allows the same `src/core/` code to power both the desktop client and the Server Edition, which executes as a pure Node.js process.

## Key Components Inside src/core/

The core directory implements critical terminal and workspace functionality through specialized modules. Each component exposes clean APIs consumed by the host platform abstraction layer.

### Platform Interface

**[`src/core/platform.ts`](https://github.com/eneskirca/nodeterm/blob/main/src/core/platform.ts)** defines the **CorePlatform** contract that abstracts the host environment. This TypeScript interface declares methods for process spawning, path resolution, and event dispatching, allowing the core to remain ignorant of whether it runs inside Electron or a standalone server.

### PTY Manager

**[`src/core/pty-manager.ts`](https://github.com/eneskirca/nodeterm/blob/main/src/core/pty-manager.ts)** handles persistent terminal sessions. It creates and manages **tmux** sessions and plain shells, emitting lifecycle events through the platform interface rather than direct Electron IPC calls. The `createPty()` function accepts parameters like `persistKey` to maintain session state across reconnections.

### Workspace Store

**[`src/core/workspace-store.ts`](https://github.com/eneskirca/nodeterm/blob/main/src/core/workspace-store.ts)** persists project metadata, node configurations, and canvas layouts. The `WorkspaceStore` class serializes workspace state to disk, decoupling the persistence layer from any renderer-specific storage mechanisms.

### Git Service

**[`src/core/git-service.ts`](https://github.com/eneskirca/nodeterm/blob/main/src/core/git-service.ts)** provides a thin wrapper around Git CLI operations. It exposes methods for repository status checks, worktree management, and commit operations used by the Source Control panel, executing commands through the abstracted platform shell.

### Agent Hook Server

**[`src/core/agents/hook-server.ts`](https://github.com/eneskirca/nodeterm/blob/main/src/core/agents/hook-server.ts)** implements an HTTP loopback server that receives webhook events from external agents. It tracks agent status and serves the hook API without dependencies on Electron's net module.

### Supporting Shared Modules

While located in `src/shared/` rather than `src/core/`, these utilities complete the service architecture:

- **[`src/shared/ipc.ts`](https://github.com/eneskirca/nodeterm/blob/main/src/shared/ipc.ts)** – Defines RPC channel names and message structures used by the core when communicating with hosts
- **[`src/shared/ssh.ts`](https://github.com/eneskirca/nodeterm/blob/main/src/shared/ssh.ts)** – Contains `execRemote()` and ControlMaster utilities for remote project handling
- **[`src/shared/agents/config.ts`](https://github.com/eneskirca/nodeterm/blob/main/src/shared/agents/config.ts)** – Maps agent configurations to model-gateway endpoints

## Platform Abstraction Implementation

The core achieves framework independence through the **Platform Interface** pattern defined in [`src/core/platform.ts`](https://github.com/eneskirca/nodeterm/blob/main/src/core/platform.ts). When running in Electron, the `src/main/` directory provides a concrete implementation of this interface that bridges to Electron's `ipcMain` and `BrowserWindow` APIs. In the Server Edition, a Node.js-specific implementation supplies the same contract using HTTP sockets or stdio streams.

This architecture means files like [`src/core/pty-manager.ts`](https://github.com/eneskirca/nodeterm/blob/main/src/core/pty-manager.ts) import only `CorePlatform` from `./platform`, never `electron` directly. The platform abstraction handles the actual transport mechanism, whether that is Electron IPC in the desktop app or WebSocket messages in the server environment.

## Working with the Core: Code Examples

The following examples demonstrate how to interact with the **Electron-free service core** from host implementations.

### Creating a Persistent Terminal Session

This example from [`src/core/pty-manager.ts`](https://github.com/eneskirca/nodeterm/blob/main/src/core/pty-manager.ts) demonstrates launching a tmux-backed PTY:

```typescript
import { CorePlatform } from "./core/platform";
import { createPty } from "./core/pty-manager";

async function startTerminal(nodeId: string) {
  const pty = await createPty({ persistKey: nodeId });
  // `pty` represents a tmux session; events emit via the platform abstraction
  return pty;
}

```

### Loading Workspace State

Access the workspace store to retrieve project data without Electron dependencies:

```typescript
import { WorkspaceStore } from "./core/workspace-store";

async function loadProject(projectId: string) {
  const store = new WorkspaceStore();
  const project = await store.load(projectId);
  // Returns serialized node data, layout, and settings
  return project;
}

```

### Executing Remote SSH Commands

The shared SSH utilities work within the core's Node.js context:

```typescript
import { execRemote } from "./shared/ssh";

async function runRemoteCommand(host: string, cmd: string) {
  const result = await execRemote(host, cmd);
  console.log("Remote output:", result.stdout);
}

```

## Summary

- The **Electron-free service core** lives in **`src/core/`**, isolated from renderer and main process code.
- **[`src/core/platform.ts`](https://github.com/eneskirca/nodeterm/blob/main/src/core/platform.ts)** provides the abstraction layer allowing the core to run in both Electron and plain Node.js environments.
- Key modules include **[`src/core/pty-manager.ts`](https://github.com/eneskirca/nodeterm/blob/main/src/core/pty-manager.ts)** for terminal sessions, **[`src/core/workspace-store.ts`](https://github.com/eneskirca/nodeterm/blob/main/src/core/workspace-store.ts)** for persistence, and **[`src/core/git-service.ts`](https://github.com/eneskirca/nodeterm/blob/main/src/core/git-service.ts)** for version control.
- Shared utilities in **`src/shared/`** (IPC definitions, SSH helpers) support core operations without importing Electron APIs.
- This architecture enables nodeterm's **Server Edition** to reuse the exact same logic as the desktop application.

## Frequently Asked Questions

### What is the purpose of separating the Electron-free service core from the main process?

The separation allows nodeterm to distribute a **Server Edition** that runs on headless Linux machines or remote servers without requiring Electron's heavy dependencies or display libraries. By isolating business logic in `src/core/`, the same PTY management, Git operations, and agent handling work identically in both the desktop GUI and the headless server.

### Can the nodeterm core run independently without Electron installed?

**Yes.** The `src/core/` directory contains no Electron imports and relies solely on Node.js standard libraries. When executed in the Server Edition, the core loads a Node.js-specific platform implementation instead of the Electron bridge, enabling operation on systems without X11 or Wayland libraries.

### How does the core communicate with the UI layer if it cannot import Electron?

Communication flows through the **Platform Interface** defined in [`src/core/platform.ts`](https://github.com/eneskirca/nodeterm/blob/main/src/core/platform.ts). The core emits events and makes requests against this abstract interface. The host environment—whether `src/main/` (Electron) or the server bootstrap—provides a concrete implementation that translates these calls into Electron IPC messages or WebSocket frames respectively.

### Which file handles persistent terminal sessions in the core?

**[`src/core/pty-manager.ts`](https://github.com/eneskirca/nodeterm/blob/main/src/core/pty-manager.ts)** manages persistent terminal sessions. It handles tmux session creation, attachment, and cleanup, using the platform abstraction to stream output rather than binding directly to Electron's `ipcRenderer` or `ipcMain` modules.