> ## Documentation Index
> Fetch the complete documentation index at: https://docs.alumio.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Filesystem: Write all items to a file

> Writes all its input items to a file and returns the path of the created file.

export const FormField = ({property, label, required = false, diType, uiPatterns, children}) => {
  const patterns = Array.isArray(uiPatterns) ? uiPatterns : uiPatterns ? [uiPatterns] : [];
  return <div style={{
    margin: '1.5rem 0'
  }}>
      <div style={{
    display: 'flex',
    alignItems: 'baseline',
    flexWrap: 'wrap',
    gap: '0.5rem',
    marginBottom: '0.25rem'
  }}>
        <strong>{label}</strong>
        <span style={{
    fontSize: '0.7rem',
    fontWeight: 600,
    textTransform: 'uppercase',
    letterSpacing: '0.04em',
    color: required ? '#6241f5' : '#6b7280'
  }}>
          {required ? 'Required' : 'Optional'}
        </span>
      </div>

      <div>{children}</div>

      {diType || patterns.length > 0 ? <p style={{
    fontSize: '0.85rem',
    color: '#6b7280',
    marginBottom: 0
  }}>
          {diType ? <>
              See the <a href={`/references/${diType}`}>{diType}</a> reference.{' '}
            </> : null}
          {patterns.length > 0 ? <>
              Accepts a <a href={`/documentation/placeholders-and-patterns/patterns#${patterns[0]}`}>pattern</a>.
            </> : null}
        </p> : null}
    </div>;
};

Use this step to gather every item flowing through it and write them all into a single file on a filesystem connection. You choose where the file goes, how the items are formatted in it, and what should happen if a file already exists at that location. After the file is written, the step passes on a single item containing the path of the file it created, so a later step can pick up that path and act on it. Because it gathers all incoming items into one file, anything after this step works with the file path rather than the original items.

This documentation describes: [Schema](/schemas/transformer-step/write-file)

## Fields

<FormField property="filesystem" label="Destination filesystem connection" required diType="filesystem">
  The filesystem connection where the file is written, such as a local folder, an SFTP server, or cloud storage.
</FormField>

<FormField property="serializer" label="Formatter" required diType="list-serializer">
  How the items are turned into the contents of the file, for example as a single CSV, NDJSON, or XML document. The formatter decides the file's structure, including any header and footer wrapped around the items.
</FormField>

<FormField property="path" label="Destination path to write the file" required>
  The path and filename to write on the chosen connection, for example `exports/products.csv`. You can use [placeholders](/references/placeholders) to build the name from data, such as including a date.
</FormField>

<FormField property="ensureDestination" label="When the file exists" diType="filesystem-ensure-destination">
  What to do when a file already exists at the destination path. Leave it empty to overwrite the existing file. Choose another option to keep both files, for example by adding a counter to the filename so each run produces a new file.
</FormField>

## Sample data

This step runs as part of a route, writing to a filesystem connection rather than transforming an item in place, so there is no before/after to show. It collects every item passing through, writes them into one file using the chosen formatter, and then outputs a single item with the path of the file it created, for example `{ "path": "exports/products.csv" }`.

A small example configuration that writes all items as a CSV to a filesystem connection:

```json Configuration theme={null}
{
  "prototype": "write-file",
  "parameters": {
    "filesystem": "my-filesystem-connection",
    "serializer": { "prototype": "csv", "parameters": {} },
    "path": "exports/products.csv"
  }
}
```
