> Part of the walkerOS documentation. Project overview and full index: <https://www.walkeros.io/llms.txt>

# Filesystem

<!-- -->

[Server](#)[ ](https://github.com/elbwalker/walkerOS/tree/main/packages/server/stores/fs)

<!-- -->

[Source code](https://github.com/elbwalker/walkerOS/tree/main/packages/server/stores/fs)[ ](https://www.npmjs.com/package/@walkeros/server-store-fs)

<!-- -->

[Package](https://www.npmjs.com/package/@walkeros/server-store-fs)

Local filesystem store for walkerOS server flows. Reads and writes files relative to a base directory with path traversal protection.

## Installation[​](#installation "Direct link to Installation")

```
npm install @walkeros/server-store-fs
```

* Integrated
* Bundled

```
import { startFlow } from '@walkeros/collector';
import { storeFsInit } from '@walkeros/server-store-fs';

await startFlow({
  stores: {
    assets: {
      code: storeFsInit,
      config: {
        settings: {
          basePath: './public',
        },
      },
    },
  },
});
```

Add to your `flow.json`:

```
"stores": {
  "assets": {
    "package": "@walkeros/server-store-fs",
    "config": {
      "settings": {
        "basePath": "./public"
      }
    }
  }
}
```

## Configuration[​](#configuration "Direct link to Configuration")

This <!-- -->store<!-- --> uses the standard <!-- -->store<!-- --> config wrapper (consent, data, env, id, ...). For the shared fields see [store<!-- --> configuration](https://www.walkeros.io/docs/stores.md#configuration). Package-specific fields live under `config.settings` and are listed below.

## Settings[​](#settings "Direct link to Settings")

| Property    | Type     | Description                                                                      | More |
| ----------- | -------- | -------------------------------------------------------------------------------- | ---- |
| `basePath*` | `string` | Root directory for file operations. All keys are resolved relative to this path. |      |

\* Required fields

## Mapping[​](#mapping "Direct link to Mapping")

This package does not define custom rule-level settings. For the standard rule fields (consent, condition, data, batch, name, policy) see [mapping](https://www.walkeros.io/docs/mapping.md).

## Examples

### Read file

Read an existing file and receive its raw bytes byte-exact

Event

```
{
  "operation": "get",
  "key": "walker.js"
}
```

Out

```
get("walker.js", "Bytes<console.log(\"walkerOS\")>")
```

### Write file

Write creates intermediate directories automatically

Event

```
{
  "operation": "set",
  "key": "js/custom/tracker.js",
  "value": "Buffer<(function(){...})()>"
}
```

Out

```
set("js/custom/tracker.js", "Buffer<(function(){...})()>")
```

## Structured vs file mode[​](#structured-vs-file-mode "Direct link to Structured vs file mode")

The fs store has two modes, decided once at init by `config.file`:

* **Structured (default):** values are structured `StoreValue` data, serialized to and from disk by the shared core codec. Use for session state, lookups, and cached responses.
* **File (`file: true`):** values persist as raw bytes byte-exact. `set()` accepts a `Uint8Array` or `string` and writes it untouched; `get()` hands the exact bytes back. Use for serving assets such as walker.js, where byte fidelity matters.

One store instance is exactly one mode. Set `file: true` on the store declaration to opt into byte-exact serving.

## API[​](#api "Direct link to API")

```
const file = await store.get('walker.js');           // StoreValue | undefined
await store.set('data.json', { ok: true });          // structured value
await store.set('walker.js', new Uint8Array([/*…*/])); // file mode: raw bytes
await store.delete('old-file.txt');                   // void
```

In file mode, `get()` returns the bytes as a `Uint8Array` leaf and `set()` rejects non-`Uint8Array`, non-`string` values with a clear error, so served assets stay intact byte-for-byte.

## File serving pattern[​](#file-serving-pattern "Direct link to File serving pattern")

Use with the file transformer to serve static assets from the local filesystem. Set `file: true` so the store persists and returns bytes byte-exact:

```
{
  "stores": {
    "assets": {
      "package": "@walkeros/server-store-fs",
      "config": {
        "settings": { "basePath": "./public" },
        "file": true
      }
    }
  },
  "transformers": {
    "file": {
      "package": "@walkeros/server-transformer-file",
      "config": { "settings": { "prefix": "/static" } },
      "env": { "store": "$store.assets" }
    }
  }
}
```

A request to `/static/walker.js` reads `./public/walker.js` from disk. Omit `file` (or set it false) for a structured key-value store instead.

## Security[​](#security "Direct link to Security")

* **Path traversal protection**: Requests with `..`, absolute paths, or backslash traversal are rejected and logged as warnings
* **Base path scoping**: All operations are restricted to the configured `basePath` directory
* **Intermediate directories**: `set()` creates parent directories automatically via `mkdir -p`

## When to use[​](#when-to-use "Direct link to When to use")

| Scenario                    | Recommended store                                                                        |
| --------------------------- | ---------------------------------------------------------------------------------------- |
| Local development           | **Filesystem**: files on disk, no credentials needed                                     |
| Docker with baked-in assets | **Filesystem**: mount or copy files into the image                                       |
| Cloud / managed deployments | [S3](https://www.walkeros.io/docs/stores/server/s3.md): files in a bucket, hot-swappable |
| Caching / ephemeral data    | Built-in [cache tier](https://www.walkeros.io/docs/stores/cache.md): in-process, no I/O  |
