---
title: "userfile"
description: "The userfile namespace — the engine's Luau API reference for userfile."
section: "API Reference"
slug: "api-userfile"
canonical: "https://origozero.ai/docs/api-userfile"
updated: "2026-09-05T23:13:47.514423132+00:00"
tags: ["api", "reference"]
---

# userfile

The `userfile` namespace — 7 functions.

## globals/userfile/pick {#globals-userfile-pick}

```lua
userfile.pick(opts: PickOpts?) -> PickResult
```

Open the user's system file picker and bring the chosen file(s)
into the engine. Yields until the user finishes (call from a coroutine /
task, like any `task.await`) and returns
`{ cancelled, files = {{ name, mime, size, bytes?, vfsPath? }} }`.
Without `writeTo` each file carries `bytes` (a binary-safe string);
with `writeTo` each carries `vfsPath` (read it with `vfs.read`).
Cancelling returns `{ cancelled = true, files = {} }`; a genuine failure
(e.g. a lost browser user-activation gesture) raises an error.

**Parameters**

- `opts` `PickOpts` _(optional)_ — Picker options (optional): multiple, folder, title, filters, writeTo.

**Returns** `PickResult` — The decoded result table.

```lua
local r = userfile.pick({ filters = {{ name = "Images", extensions = {"png","jpg"} }} })
if not r.cancelled then vfs.write("/source/textures/wall.png", r.files[1].bytes) end
```

## globals/userfile/pickFolder {#globals-userfile-pickfolder}

```lua
userfile.pickFolder(opts: PickOpts?) -> PickResult
```

Convenience for `userfile.pick({ folder = true })` — pick a whole
directory tree. Yields until the user finishes and returns the same
result table as `pick`. On the web this degrades to a multi-file selection.

**Parameters**

- `opts` `PickOpts` _(optional)_ — Picker options (optional); `folder` is forced true.

**Returns** `PickResult` — The decoded result table.

```lua
local r = userfile.pickFolder({ writeTo = "/source/imported/" })
```

## modules/userfile/README {#modules-userfile-readme}

```lua
require("@builtin/modules/api/engine/userfile") -- userfile (also available as global 'userfile')
```

User-system → engine file upload. Opens the user's own file picker (native OS dialog / Android / web browser) and brings the chosen file(s) into the engine. Public Luau surface over the `__userfile` Internal FFI namespace.

Usage: local userfile = require("@builtin/modules/api/engine/userfile")
Also available as global: userfile

## modules/userfile/pick {#modules-userfile-pick}

```lua
pick(opts: PickOpts?): PickResult
```

Open the user's system file picker and bring the chosen file(s)
into the engine. Yields until the user finishes (call from a coroutine /
task, like any `task.await`) and returns
`{ cancelled, files = {{ name, mime, size, bytes?, vfsPath? }} }`.
Without `writeTo` each file carries `bytes` (a binary-safe string);
with `writeTo` each carries `vfsPath` (read it with `vfs.read`).
Cancelling returns `{ cancelled = true, files = {} }`; a genuine failure
(e.g. a lost browser user-activation gesture) raises an error.

**Parameters**

- `opts` `PickOpts?` _(optional)_ — Picker options (optional): multiple, folder, title, filters, writeTo.

```lua
local r = userfile.pick({ filters = {{ name = "Images", extensions = {"png","jpg"} }} })
if not r.cancelled then vfs.write("/source/textures/wall.png", r.files[1].bytes) end
```

## modules/userfile/pickFolder {#modules-userfile-pickfolder}

```lua
pickFolder(opts: PickOpts?): PickResult
```

Convenience for `userfile.pick({ folder = true })` — pick a whole
directory tree. Yields until the user finishes and returns the same
result table as `pick`. On the web this degrades to a multi-file selection.

**Parameters**

- `opts` `PickOpts?` _(optional)_ — Picker options (optional); `folder` is forced true.

```lua
local r = userfile.pickFolder({ writeTo = "/source/imported/" })
```

## typed/builtin//modules/api/engine/userfile/userfile/pick {#typed-builtin-modules-api-engine-userfile-userfile-pick}

```lua
userfile.pick(opts: PickOpts?) -> PickResult
```

Open the user's system file picker and bring the chosen file(s)
into the engine. Yields until the user finishes (call from a coroutine /
task, like any `task.await`) and returns
`{ cancelled, files = {{ name, mime, size, bytes?, vfsPath? }} }`.
Without `writeTo` each file carries `bytes` (a binary-safe string);
with `writeTo` each carries `vfsPath` (read it with `vfs.read`).
Cancelling returns `{ cancelled = true, files = {} }`; a genuine failure
(e.g. a lost browser user-activation gesture) raises an error.

**Parameters**

- `opts` `PickOpts` _(optional)_ — Picker options (optional): multiple, folder, title, filters, writeTo.

**Returns** `PickResult` — The decoded result table.

```lua
local r = userfile.pick({ filters = {{ name = "Images", extensions = {"png","jpg"} }} })
if not r.cancelled then vfs.write("/source/textures/wall.png", r.files[1].bytes) end
```

## typed/builtin//modules/api/engine/userfile/userfile/pickFolder {#typed-builtin-modules-api-engine-userfile-userfile-pickfolder}

```lua
userfile.pickFolder(opts: PickOpts?) -> PickResult
```

Convenience for `userfile.pick({ folder = true })` — pick a whole
directory tree. Yields until the user finishes and returns the same
result table as `pick`. On the web this degrades to a multi-file selection.

**Parameters**

- `opts` `PickOpts` _(optional)_ — Picker options (optional); `folder` is forced true.

**Returns** `PickResult` — The decoded result table.

```lua
local r = userfile.pickFolder({ writeTo = "/source/imported/" })
```
