Functions
Run server-side TypeScript in Rayfin — when to use functions instead of client-side data access, and how to enable and scaffold them.
Rayfin functions are server-side TypeScript user-defined functions (UDFs) that run in the
Fabric runtime and are invocable from your frontend through RayfinClient with full type
safety, the same way client.data.<Entity> is typed.
Warning
Functions are experimental and are not available in every Fabric region or tenant.
@microsoft/rayfin-functions may change substantially between releases. Confirm the
service deploys in your own workspace before you design an app around it.
When to use functions
Reach for a function whenever logic needs to run on the backend rather than the frontend:
- Sensitive operations — secrets, API keys, or privileged access to external resources that must never reach client-side code.
- Business logic that must not be tampered with — anything a client could otherwise bypass or forge by calling your data API directly.
- Server-side validation — checks that have to be trustworthy, not just present in the UI.
- Aggregation or transformation — computing or reshaping data before it reaches the client, instead of shipping raw rows and doing the work in the browser.
If a frontend feature needs trusted server-side behavior, implement it as a function rather
than adding an ad hoc backend service. For everything else — reading and writing your own
entities — use client.data.<Entity> directly; it's already
authenticated and type-safe, and a function would only add a hop.
How functions fit the architecture
A function is registered with udf.func(name, handler, []) in your functions project. Inside
the handler, RayfinContext.getDataClient() gives you the same typed data client used on the
frontend (.select().where().execute()), so a function can read and write your entities with
the same query chain you already know. Functions can also declare connections to external
services — see Connections — so they can call out to
Fabric-managed resources like SQL, Key Vault, or OneLake using delegated auth instead of
long-lived secrets.
From the frontend, a function is just another typed call: client.functions.<name>.invoke().
See Calling functions from your app for the client side.
Enable functions
Set the functions flag in rayfin/rayfin.yml:
services:
functions:
enabled: trueScaffold a functions project
npx rayfin functions initThis scaffolds rayfin/functions/, installs its dependencies, and generates the initial
types.ts schema. Pass --force to re-scaffold, overwriting existing files:
npx rayfin functions init --forceSee Writing a function for the project layout and how to register your first function.
In this section
- Writing a function — project layout,
function_app.ts,RayfinContext, and generated types. - Connections — delegated auth to external services like SQL, Key Vault, and OneLake.
- Calling functions from your app — the typed
FunctionClientand error handling. - Deploying functions — how functions ship alongside the rest of your app.
I need a piece of logic in my Rayfin app to run on the server instead of the client (explain
what it does and why it shouldn't run in the browser).
In rayfin/rayfin.yml, enable services.functions. Then run `npx rayfin functions init` if
rayfin/functions/ doesn't exist yet, and add a new function in
rayfin/functions/src/function_app.ts using udf.func(name, handler, []). Use
RayfinContext<AppSchema> if the function needs typed access to my entities via
ctx.getDataClient().
After adding it, deploy it with `npx rayfin up` (or `npx rayfin up functions deploy` to push
just the functions change) and tell me how to call it from the frontend.React integration
An auth context, a useAuth hook, and route guarding for React apps built on the Rayfin auth client with Fabric SSO.
Writing a function
The rayfin/functions project layout, registering functions with udf.func in function_app.ts, typed data access, and the auto-generated types.ts schema.