Getting Started¶
Prerequisites¶
- Node.js v20+
- UiPath CLI with the functions tool installed:
1. Create a project¶
This scaffolds a TypeScript project with a hello function, installs dependencies, and creates uipath.json. Use -l js for JavaScript.
Python Functions
uip functions new also supports --language py for Python projects. Python Functions are a separate runtime with different capabilities — see the Python Functions documentation for that path.
Options:
| Flag | Description |
|---|---|
-l, --language <lang> |
ts (default) or js for this guide; py/python for Python Functions |
--empty |
Skip the hello world function (JS/TS only) |
The generated project structure:
my-functions/
├── functions/
│ └── hello.ts # your functions go here — one function per file
├── uipath.json # maps function names → entry points
├── package.json
└── tsconfig.json
uipath.json example:
The functions/ folder is authoritative¶
You do not maintain the functions map by hand. serve, debug, pack and push all
rewrite it from the folder contents first, so hand edits are overwritten — including in
the deployed container, which re-syncs from the packaged functions/ folder when it starts
the server.
The rules discovery applies, in full:
| Registered as a function | every .ts/.js file directly inside functions/ |
| Skipped | names starting with _ (e.g. _helpers.ts), and .d.ts files |
| Not discovered at all | subfolders — functions/lib/util.ts is never registered, and a hand-written map entry pointing at one is pruned on the next sync |
| Key | the filename without its extension, so functions/create-order.ts → "create-order" |
Discovery is by filename, not by content: a file lands in the map whether or not it defines a
function. Every registered file must therefore default-export its function definition, normally
the result of defineFunction(...); only the default export is served. The call may sit behind
your own helper (export default appFunction({...}) where appFunction returns
defineFunction(...)); the CLI then reads the contract by executing the module instead of
statically, and the runtime rejects the file by name if what it exports is not a function
definition. defineSchema<T>() markers are lowered only inside a literal defineFunction(...)
call — behind a helper, declare input/output as a JSON Schema literal or a zod schema.
Anything else that lives next to your functions is a helper, and needs to be either
_-prefixed or moved out of functions/ (e.g. to lib/). Both work; the _ prefix is
handy when you want the helper to stay beside its function.
functions/
├── create-order.ts # registered → "create-order"
├── _validate.ts # skipped (helper)
└── types.d.ts # skipped
lib/
└── http.ts # not in functions/, so never registered
serve, debug, pack and push check for the default export and fail with the
offending file named before generating or uploading anything, so a stray helper cannot reach
a deployment. Left unchecked it would break the whole package rather than one route: the
generated aggregator imports every registered file, and one unloadable import takes down every
endpoint.
2. Run locally¶
Starts a hot-reload server on http://localhost:7070. The function is immediately callable:
curl -X POST http://localhost:7070/hello \
-H "Content-Type: application/json" \
-d '{"name":"Alice"}'
# {"message":"Hello, Alice!"}
For local access to Orchestrator, your function handlers read credentials from environment variables (UIPATH_ACCESS_TOKEN, UIPATH_BASE_URL, UIPATH_ORG_ID, UIPATH_TENANT_ID). Put them in a .env file at the project root:
UIPATH_ACCESS_TOKEN=<OAuth token>
UIPATH_BASE_URL=https://cloud.uipath.com
UIPATH_ORG_ID=<org-UUID>
UIPATH_TENANT_ID=<tenant-UUID>
serve loads that file on both runtimes — it passes --env-file to Node (through tsx) and to Deno — so no shell preloading is needed. Exporting the variables in your shell instead works just as well.
Note
.env is loaded only by serve (and debug). uip functions run takes its platform coordinates from the runtime-context file the host writes, not from the environment — see FunctionContext — platform.
3. Pack¶
Creates .uipath/<name>.<version>.nupkg from package.json name and version. Re-packing the same version overwrites the file.
4. Publish to Orchestrator¶
Log in first — uip login stores your session and publish picks it up automatically:
Fetches available process feeds and prompts for selection. For CI, pass credentials explicitly and skip the interactive picker with --feed-id:
uip functions publish \
--url https://cloud.uipath.com \
--org <org> \
--tenant <tenant> \
--token $UIPATH_ACCESS_TOKEN \
--feed-id <feed-uuid>
After publishing, go to Orchestrator → Automations → Processes, find your package, and update the release to the latest version. This triggers Orchestrator to read the new manifest and sync API Triggers. See Deployment — After publish.
5. Push to Studio Web (optional)¶
Diffs local files against the Studio Web project and uploads only what changed. Create the project in Studio Web first to get the project ID.