# Watch sandbox directory for changes (/docs/filesystem/watch)

<!-- agent-signals: reading_time_min: 4 · est_tokens: 2183 · updated: 2026-07-30 -->
Related: [Download data from sandbox](/docs/filesystem/download.md), [Get information about a file or directory](/docs/filesystem/info.md), [Attach custom metadata to files](/docs/filesystem/metadata.md), [Read & write files](/docs/filesystem/read-write.md), [Upload data to sandbox](/docs/filesystem/upload.md), [Download data from volume](/docs/volumes/download.md)

You can watch a directory for changes using the `files.watchDir()` method in JavaScript and `files.watch_dir()` method in Python.

<Note>
  Since events are tracked asynchronously, their delivery may be delayed.
  It's recommended not to collect or close watcher immediately after making a change.
</Note>

<CodeGroup>
  <CodeBlockTabs defaultValue="JavaScript & TypeScript" groupId="javascript-typescript+python">
    <CodeBlockTabsList>
      <CodeBlockTabsTrigger value="JavaScript & TypeScript">
        JavaScript & TypeScript
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="Python">
        Python
      </CodeBlockTabsTrigger>
    </CodeBlockTabsList>

    <CodeBlockTab value="JavaScript & TypeScript">
      ```js highlight={7-12}  
      import { Sandbox, FilesystemEventType } from 'e2b'

      const sandbox = await Sandbox.create()
      const dirname = '/home/user'

      // Start watching directory for changes
      const handle = await sandbox.files.watchDir(dirname, async (event) => {
        console.log(event)
        if (event.type === FilesystemEventType.WRITE) {
          console.log(`wrote to file ${event.name}`)
        }
      })

      // Trigger file write event
      await sandbox.files.write(`${dirname}/my-file`, 'hello')
      ```
    </CodeBlockTab>

    <CodeBlockTab value="Python">
      ```python highlight={7,12-16}  
      from e2b import Sandbox, FilesystemEventType

      sandbox = Sandbox.create()
      dirname = '/home/user'

      # Watch directory for changes
      handle = sandbox.files.watch_dir(dirname)
      # Trigger file write event
      sandbox.files.write(f"{dirname}/my-file", "hello")

      # Retrieve the latest new events since the last `get_new_events()` call
      events = handle.get_new_events()
      for event in events:
        print(event)
        if event.type == FilesystemEventType.WRITE:
          print(f"wrote to file {event.name}")
      ```
    </CodeBlockTab>
  </CodeBlockTabs>
</CodeGroup>

## Recursive watching [#recursive-watching]

You can enable recursive watching using the parameter `recursive`.

<Note>
  When rapidly creating new folders (e.g., deeply nested path of folders), events other than `CREATE` might not be emitted. To avoid this behavior, create the required folder structure in advance.
</Note>

<CodeGroup>
  <CodeBlockTabs defaultValue="JavaScript & TypeScript" groupId="javascript-typescript+python">
    <CodeBlockTabsList>
      <CodeBlockTabsTrigger value="JavaScript & TypeScript">
        JavaScript & TypeScript
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="Python">
        Python
      </CodeBlockTabsTrigger>
    </CodeBlockTabsList>

    <CodeBlockTab value="JavaScript & TypeScript">
      ```js highlight={13,17}  
      import { Sandbox, FilesystemEventType } from 'e2b'

      const sandbox = await Sandbox.create()
      const dirname = '/home/user'

      // Start watching directory for changes
      const handle = await sandbox.files.watchDir(dirname, async (event) => {
        console.log(event)
        if (event.type === FilesystemEventType.WRITE) {
          console.log(`wrote to file ${event.name}`)
        }
      }, {
        recursive: true
      })

      // Trigger file write event
      await sandbox.files.write(`${dirname}/my-folder/my-file`, 'hello')
      ```
    </CodeBlockTab>

    <CodeBlockTab value="Python">
      ```python highlight={7,9}  
      from e2b import Sandbox, FilesystemEventType

      sandbox = Sandbox.create()
      dirname = '/home/user'

      # Watch directory for changes
      handle = sandbox.files.watch_dir(dirname, recursive=True)
      # Trigger file write event
      sandbox.files.write(f"{dirname}/my-folder/my-file", "hello")

      # Retrieve the latest new events since the last `get_new_events()` call
      events = handle.get_new_events()
      for event in events:
        print(event)
        if event.type == FilesystemEventType.WRITE:
          print(f"wrote to file {event.name}")
      ```
    </CodeBlockTab>
  </CodeBlockTabs>
</CodeGroup>

## Including entry information [#including-entry-information]

You can include information about the affected file or directory in each event using the parameter `includeEntry` in JavaScript and `include_entry` in Python.
When enabled, each event carries the entry's information — such as its path, type, and size — in the `entry` field.

<Note>
  Entry information may be unset for remove events since the path no longer exists.
  Including entry information requires templates with envd version `v0.6.3` or above — using the `includeEntry` / `include_entry` option on older sandboxes will throw an error.
</Note>

<CodeGroup>
  <CodeBlockTabs defaultValue="JavaScript & TypeScript" groupId="javascript-typescript+python">
    <CodeBlockTabsList>
      <CodeBlockTabsTrigger value="JavaScript & TypeScript">
        JavaScript & TypeScript
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="Python">
        Python
      </CodeBlockTabsTrigger>
    </CodeBlockTabsList>

    <CodeBlockTab value="JavaScript & TypeScript">
      ```js highlight={10}  
      import { Sandbox } from 'e2b'

      const sandbox = await Sandbox.create()
      const dirname = '/home/user'

      // Start watching directory for changes
      const handle = await sandbox.files.watchDir(dirname, async (event) => {
        console.log(event.type, event.name, event.entry?.path, event.entry?.type)
      }, {
        includeEntry: true
      })

      // Trigger file write event
      await sandbox.files.write(`${dirname}/my-file`, 'hello')
      ```
    </CodeBlockTab>

    <CodeBlockTab value="Python">
      ```python highlight={7,14}  
      from e2b import Sandbox

      sandbox = Sandbox.create()
      dirname = '/home/user'

      # Watch directory for changes
      handle = sandbox.files.watch_dir(dirname, include_entry=True)
      # Trigger file write event
      sandbox.files.write(f"{dirname}/my-file", "hello")

      # Retrieve the latest new events since the last `get_new_events()` call
      events = handle.get_new_events()
      for event in events:
        print(event.type, event.name, event.entry.path if event.entry else None)
      ```
    </CodeBlockTab>
  </CodeBlockTabs>
</CodeGroup>

## Watching network filesystem mounts [#watching-network-filesystem-mounts]

By default, watching paths on network filesystem mounts (NFS, CIFS, SMB, FUSE) is rejected. You can explicitly opt in using the parameter `allowNetworkMounts` in JavaScript and `allow_network_mounts` in Python.

<Note>
  Events on network mounts may be unreliable or not delivered at all, which is why the explicit opt-in is required.

  Changes made by another client outside of the sandbox (for example, a different machine writing to the same network share) are **not** propagated to the watcher — only changes made from within the sandbox are detected.
</Note>

<Note>
  Watching network mounts requires templates with envd version `v0.6.4` or above — using the `allowNetworkMounts` / `allow_network_mounts` option on older sandboxes will throw an error.
</Note>

<CodeGroup>
  <CodeBlockTabs defaultValue="JavaScript & TypeScript" groupId="javascript-typescript+python">
    <CodeBlockTabsList>
      <CodeBlockTabsTrigger value="JavaScript & TypeScript">
        JavaScript & TypeScript
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="Python">
        Python
      </CodeBlockTabsTrigger>
    </CodeBlockTabsList>

    <CodeBlockTab value="JavaScript & TypeScript">
      ```js highlight={10}  
      import { Sandbox } from 'e2b'

      const sandbox = await Sandbox.create()
      const dirname = '/mnt/nfs-share/my-dir'

      // Start watching a directory on a network mount for changes
      const handle = await sandbox.files.watchDir(dirname, async (event) => {
        console.log(event.type, event.name)
      }, {
        allowNetworkMounts: true
      })

      // Trigger file write event
      await sandbox.files.write(`${dirname}/my-file`, 'hello')
      ```
    </CodeBlockTab>

    <CodeBlockTab value="Python">
      ```python highlight={7,14}  
      from e2b import Sandbox

      sandbox = Sandbox.create()
      dirname = '/mnt/nfs-share/my-dir'

      # Watch a directory on a network mount for changes
      handle = sandbox.files.watch_dir(dirname, allow_network_mounts=True)
      # Trigger file write event
      sandbox.files.write(f"{dirname}/my-file", "hello")

      # Retrieve the latest new events since the last `get_new_events()` call
      events = handle.get_new_events()
      for event in events:
        print(event.type, event.name)
      ```
    </CodeBlockTab>
  </CodeBlockTabs>
</CodeGroup>
