# Difference Between destroy and recycle in TerminalTransport: Session Lifecycle Management

> Understand the TerminalTransport destroy vs recycle difference. Destroy permanently ends sessions, recycle temporarily stops them for respawning with the same ID. Learn session lifecycle management.

- Repository: [eneskirca/nodeterm](https://github.com/eneskirca/nodeterm)
- Tags: deep-dive
- Published: 2026-08-25

---

**In the `TerminalTransport` interface, `destroy` permanently terminates a PTY session when a terminal node is deleted, while `recycle` temporarily ends a session to allow the same node ID to be respawned in a new working directory.**

The `TerminalTransport` interface in the **eneskirca/nodeterm** repository defines the contract for managing terminal sessions across the application. Located in [`src/renderer/terminal/transport.ts`](https://github.com/eneskirca/nodeterm/blob/main/src/renderer/terminal/transport.ts), this abstraction handles session creation, resizing, and termination. Understanding the **difference between `destroy` and `recycle`** is essential for developers working with session persistence or implementing custom transport layers.

## Understanding TerminalTransport Session Lifecycle

Both methods terminate a PTY (pseudo-terminal) session, but they serve distinct lifecycle intents. The interface defines these methods to handle two scenarios: permanent node removal and temporary session turnover. While the underlying tmux kill operation may be identical in the concrete implementation, the semantic difference determines how co-viewers and the canvas state respond to the action.

## The destroy Method: Permanent Session Termination

The `destroy(persistKey, opts?)` method is invoked when a terminal node is permanently removed from the canvas. This occurs when a user clicks the **×** button or invokes a *Delete* action.

Key characteristics of `destroy`:

- **Permanent removal**: The session ends definitively because the node itself is being deleted from the workspace.
- **everySocket option**: The optional `opts.everySocket` flag extends the kill operation to every local tmux socket that may hold the session name. This is specifically used by the speculative "kill all" action in the *Session-Memory* panel to ensure complete cleanup of stray sockets.
- **Co-viewer notification**: Peer viewers receive a *closed by \<peer\>* notification and are explicitly prohibited from respawning the session.

According to the interface definition in [`src/renderer/terminal/transport.ts`](https://github.com/eneskirca/nodeterm/blob/main/src/renderer/terminal/transport.ts), this method represents the final lifecycle event for a terminal session associated with a specific node.

## The recycle Method: Session Turnover Without Node Deletion

The `recycle(persistKey)` method temporarily ends a node's session so that the **same node ID can be respawned**, typically when the node is moved into a worktree or changes its underlying working directory.

Key characteristics of `recycle`:

- **Session turnover**: While the underlying tmux kill matches `destroy`, the intent is opposite—the node remains on the canvas, and a replacement session will be created immediately after.
- **Worktree migration**: This is used when a node stays visually present but its underlying directory changes, requiring a fresh shell in the new location.
- **Co-viewer handling**: Peers receive an `onRecycled` event. If a replacement session is already live (`ready: true`), the terminal automatically recreates and re-attaches; if not (`ready: false`), the user must manually reopen the node.

This method preserves the node's identity and position while refreshing its underlying shell session.

## destroy vs recycle: A Direct Comparison

Understanding the semantic differences helps prevent accidental data loss or session desynchronization:

- **`destroy(persistKey, opts?)`** – Use this for **permanent removal** when the terminal node is deleted from the canvas. Prevents session resurrection and optionally clears all related tmux sockets via the `everySocket` flag.

- **`recycle(persistKey)`** – Use this for **temporary session turnover** when the node persists but requires a new shell (e.g., directory changes). Allows seamless respawning with the same node ID and notifies peers to reattach or wait.

The critical distinction is that `destroy` treats the session as dead and unrecoverable, while `recycle` treats it as transiently paused with an imminent replacement.

## Implementation in LocalTransport

The concrete `LocalTransport` implementation follows the `TerminalTransport` interface contract defined in [`src/renderer/terminal/transport.ts`](https://github.com/eneskirca/nodeterm/blob/main/src/renderer/terminal/transport.ts). Both methods execute similar tmux kill commands, but the surrounding logic differs:

- `destroy` updates session metadata to mark the session as permanently closed.
- `recycle` triggers the `onRecycled` event pipeline and maintains the node's registry entry for immediate respawning.

## Practical Code Examples

When deleting a terminal node permanently:

```typescript
// Permanent deletion of a terminal node
await transport.destroy(nodeId);

// Optional: Clear all stray tmux sockets (Session-Memory panel usage)
await transport.destroy(nodeId, { everySocket: true });

```

When moving a terminal node into a worktree (same node ID, new directory):

```typescript
// Temporary recycle for worktree migration
await transport.recycle(nodeId);
// The renderer listens for onRecycled and automatically creates a fresh
// session attached to the new worktree directory.

```

## Summary

- **`destroy`** permanently terminates a PTY session when the terminal node is deleted from the canvas, with optional socket cleanup via the `everySocket` parameter.
- **`recycle`** temporarily ends a session to allow the same node ID to be respawned with a new working directory, triggering `onRecycled` events for co-viewers.
- Both methods use similar underlying tmux kill operations, but `destroy` prohibits session resurrection while `recycle` expects immediate replacement.
- Co-viewers receive *closed by \<peer\>* notifications for destroyed sessions and `onRecycled` events for recycled sessions, with different reattachment behaviors for each.

## Frequently Asked Questions

### What happens to co-viewers when a terminal session is destroyed?

Co-viewers receive a *closed by \<peer\>* notification and are prohibited from respawning the session. The session is marked as permanently terminated across all connected clients, ensuring no ghost sessions remain active on peer machines.

### Can a recycled terminal session be automatically restored?

Yes. If the replacement session is already live (`ready: true`) when the `onRecycled` event fires, the terminal automatically recreates and re-attaches the session for all viewers. If the session is not ready (`ready: false`), the user must manually reopen the node to establish the new connection in the updated working directory.

### When should I use the everySocket option with destroy?

Use the `everySocket` flag when you need to ensure complete cleanup of any stray tmux sockets that might hold the session name. This is specifically designed for the "kill all" action in the *Session-Memory* panel to prevent ghost sessions from consuming resources after bulk deletion operations.

### Is the underlying tmux kill operation different between destroy and recycle?

No. In the `LocalTransport` implementation, the underlying tmux kill command is identical. The difference lies in the lifecycle intent and post-kill behavior: `destroy` treats the session as permanently dead and removes the node from the canvas, while `recycle` treats it as transiently paused with an imminent replacement session using the same node ID.