<!-- BusyBot node reference — https://busybot.net/tools/write-to-file/ -->

> Node: Write to File (`write_to_file`) · Action (binary) · v1
> Category: Core Nodes · Credentials: none
> Updated: 2026-08-16

# Write to File

> Save data to a file

## Overview

Writes text content to a relative path on the local filesystem (per-item). Supports expressions like {{ $json.field }} in both the path and the content, so each item can produce its own file. It can also write a binary file straight from an upstream node instead of text, and it attaches the file it wrote to the output item as binary data so later nodes can pick it up.

**Category:** Core Nodes  
**Tool Name:** `write_to_file`  
**Version:** 1

**Appearance:** Icon: `writeFile` | Color: `#64748b`

## Node Type

**Action (Binary)** — handles file/binary data operations

## Input / Output

| Direction | Port(s) |
|-----------|--------|
| Input | `Input` |
| Output | `Output`, `Error` |

## Credentials

This tool does not require any credentials.

### Parameters

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| Base Directory | `string` | No | `.` | Base directory to resolve writes from, itself resolved inside this execution's own files directory. `.` means that directory. `..` segments are rejected and every file path is constrained to stay inside it. |
| File Path (Relative) | `string` | Yes | `{{ $json.path }}` | Relative file path to write to. Supports expressions like {{ $json.path }}. Must remain within Base Directory. |
| Content | `string` | Yes | `{{ $json.content }}` | Text content to write. Supports expressions like {{ $json.content }} (or any other field). |
| Write Mode | `options` | No | `overwrite` | Overwrite replaces the file contents. Append adds to the end of the file. |
| | | | | Options: `overwrite`, `append` |
| Encoding | `options` | No | `utf8` | Text encoding used when writing the file. |
| | | | | Options: `utf8`, `utf16le`, `latin1`, `ascii` |
| Create Directories | `boolean` | No | `true` | If true, creates parent directories automatically. |
| Enforce Text Extensions | `boolean` | No | `true` | If true, rejects writes to files whose extension is not in Allowed Extensions (basic guardrail for this simplified tool). |
| Allowed Extensions | `string` | No | `.txt,.md,.js,.ts,.json,.csv,.html,.css,.log,.yaml,.yml` | Comma-separated list of allowed file extensions (used only if Enforce Text Extensions is enabled). _(shown when Enforce Text Extensions is `true`)_ |
| Include Input Fields | `boolean` | No | `true` | If true, copies the input item JSON into the output item JSON. |
| Result Field Name | `string` | No | `fileWrite` | Where to place the write result metadata on the output JSON. |
| Stringify Non-String Content | `boolean` | No | `true` | If true, non-string content values are JSON.stringified (pretty) before writing. |
| Binary Property | `string` | No | — | If set, writes binary data from this property instead of text content. Names are case-sensitive — see the upstream node's Binary Data panel for the exact names to use. |
| Max Concurrency | `number` | No | `25` | Maximum number of items to process concurrently. |

## Output Data

One output item per input item. The write result is written to the property named by **Result Field Name** (`fileWrite` by default); the input item JSON is copied alongside it unless **Include Input Fields** is off.

The result object carries:

- `ok` — `true` when the write succeeded
- `baseDirectory` — the base directory the write was resolved from
- `relativePath` — the resolved relative path that was written
- `fullPath` — the full path of the written file
- `writeMode` — `overwrite` or `append`
- `encoding` — the encoding used
- `bytesWritten` — number of bytes written
- `wroteAt` — epoch-millisecond timestamp of the write

The file itself is attached to the output item as binary data on the `data` property (with its file name, MIME type and size), merged with any binary the item already carried, so a downstream node can upload or forward it without re-reading the file.

Reference the result downstream by expression, e.g. `{{ $json.fileWrite.relativePath }}`.

## Usage Examples

- save the results to a JSON file
- write the data to CSV
- export the processed items
- create an output file with the results
- store the response locally

## Example Configuration

Basic file write:

```json
{
  "id": "write_file_1",
  "type": "write_to_file",
  "typeVersion": 1,
  "position": [400, 200],
  "parameters": {
    "relativePath": "output/result.txt",
    "content": "Hello World!"
  }
}
```

Dynamic content with expressions:

```json
{
  "id": "write_dynamic_file",
  "type": "write_to_file",
  "typeVersion": 1,
  "position": [400, 200],
  "parameters": {
    "relativePath": "reports/{{ $json.filename }}.txt",
    "content": "Report for {{ $json.name }}: {{ $json.data }}",
    "writeMode": "overwrite",
    "createDirs": true
  }
}
```

Append mode with custom settings:

```json
{
  "id": "append_to_log",
  "type": "write_to_file",
  "typeVersion": 1,
  "position": [400, 200],
  "parameters": {
    "baseDirectory": "./logs",
    "relativePath": "application.log",
    "content": "[{{ new Date().toISOString() }}] {{ $json.logMessage }}\n",
    "writeMode": "append",
    "encoding": "utf8",
    "includeInput": false,
    "resultFieldName": "logResult"
  }
}
```

With extension enforcement:

```json
{
  "id": "write_with_validation",
  "type": "write_to_file",
  "typeVersion": 1,
  "position": [400, 200],
  "parameters": {
    "relativePath": "data/{{ $json.id }}.json",
    "content": "{{ $json }}",
    "enforceTextExtensions": true,
    "allowedExtensions": "json,txt,csv,md",
    "stringifyObjects": true,
    "maxConcurrency": 5
  }
}
```

Minimal configuration, using defaults:

```json
{
  "id": "simple_write",
  "type": "write_to_file",
  "typeVersion": 1,
  "position": [400, 200],
  "parameters": {
    "relativePath": "{{ $json.path }}",
    "content": "{{ $json.content }}"
  }
}
```

Use when generating reports or documentation files:

```json
{
  "parameters": {
    "relativePath": "reports/{{ $json.date }}/{{ $json.reportType }}.md",
    "content": "# {{ $json.title }}\n\n{{ $json.body }}",
    "createDirs": true,
    "enforceTextExtensions": true,
    "allowedExtensions": "md,txt,html"
  }
}
```

Use for exporting structured data:

```json
{
  "parameters": {
    "relativePath": "exports/{{ $json.tableName }}.json",
    "content": "{{ $json.data }}",
    "stringifyObjects": true,
    "enforceTextExtensions": true,
    "allowedExtensions": "json,csv"
  }
}
```

Use for collecting and writing log entries:

```json
{
  "parameters": {
    "baseDirectory": "./logs",
    "relativePath": "{{ $json.service }}.log",
    "content": "[{{ $json.timestamp }}] {{ $json.level }}: {{ $json.message }}\n",
    "writeMode": "append",
    "enforceTextExtensions": false
  }
}
```

Use with high concurrency for processing multiple files:

```json
{
  "parameters": {
    "relativePath": "output/{{ $json.id }}.txt",
    "content": "{{ $json.processedContent }}",
    "maxConcurrency": 20,
    "createDirs": true,
    "includeInput": true,
    "resultFieldName": "writeStatus"
  }
}
```

### Error Handling

| Mode | Behavior |
|------|----------|
| **stop** | Halts workflow on first error |
| **continue** | Skips failed items, passes successful ones through |
| **errorPort** | Routes failed items to Error output port |

## Tips

Writes the resolved text content (or a binary property from the item) to a file inside the execution sandbox, one file per item. Use when you need to save processed data as a downloadable file — the shape of the file is whatever you put in Content, so build JSON or CSV upstream. Produces items containing the write result and the written file attached as binary data.

### Behavior notes

- **Every path stays inside Base Directory.** An absolute path, an empty path, or a path that climbs out of the base directory is rejected as an item error. Base Directory itself is resolved inside this execution's own files directory, so writes can never escape the sandbox.
- **Extension enforcement is on by default.** Writing a `.pdf` or an extensionless file fails until you add the extension to Allowed Extensions or turn Enforce Text Extensions off.
- **Binary Property wins over Content.** When it is set and the item actually carries that binary property, the file is written from the binary bytes and the text content is ignored; otherwise the node falls back to writing the resolved text.
- **Non-string content** (an object pulled straight from `{{ $json }}`) is written as pretty-printed JSON while Stringify Non-String Content is on.