Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Fabric Apps projects separate backend configuration, data models, and frontend code. The exact layout depends on the template. The default blankapp template resolves to Universal App, an npm workspace with separate frontend, data, and shared packages.
Folder layout
The default Universal App scaffold has the following structure:
your-project/
├── rayfin/
│ ├── .env
│ ├── rayfin.yml
│ └── tsconfig.json
├── packages/
│ ├── frontend/
│ │ ├── src/
│ │ └── package.json
│ ├── data/
│ │ └── src/index.ts
│ └── shared/
│ └── src/index.ts
├── package.json
├── tsconfig.json
└── README.md
| Location | Ownership |
|---|---|
rayfin/ |
Backend configuration and active environment values. |
packages/frontend/ |
Browser UI, client initialization, and frontend build. |
packages/data/ |
Decorated runtime entity classes and schema registration. |
packages/shared/ |
Isomorphic record contracts and schema types shared with the frontend. Don't put backend-only code here. |
Data is disabled in the base scaffold. Enable it when your app needs persisted records:
npm run pack:add -- data-modeling
The capability adds a starter entity and shared contract and enables the data service. For entity authoring and MSSQL dialect configuration, see Define data models.
Flat-template alternative
Some templates and existing apps use a flat layout with frontend code in root src/, entities in rayfin/data/, and a schema type map in rayfin/data/schema.ts. This layout remains valid. Don't move files or create duplicate packages just to match another template. Read the service paths in rayfin/rayfin.yml to find the directories your project actually builds.
Key configuration files
rayfin/rayfin.yml
The rayfin/rayfin.yml file is the main configuration file for your Fabric Apps backend. It controls which services run during local development and supports environment variable interpolation for dynamic configuration values.
The default workspace uses explicit service paths. The following example shows those paths with Data enabled for an app that needs a database:
id: my-app
name: my-app
version: 1.0.0
services:
auth:
enabled: true
allowedRedirectUris:
- http://localhost:5173
fabric:
enabled: true
externalEntraExchange: true
password:
enabled: false
data:
enabled: true
dialect: mssql
path: packages/data
buildCommand: npm run build
staticHosting:
enabled: true
path: packages/frontend
folder: dist
buildCommand: npm run build:fabric
indexDocument: index.html
assetAccess: protected
Service path values are relative to the project root. Build commands run from the resolved service directory. Functions initialization also records services.functions.path when it selects a workspace package such as packages/functions. Flat projects can use the existing rayfin/functions location. See Use Functions.
The configuration includes these key fields:
Top-level fields
| Field | Type | Required | Description |
|---|---|---|---|
id |
string |
Yes | Project slug used as the Docker Compose project name and Fabric item identifier. |
name |
string |
Yes | Human-readable project display name. |
version |
string |
Yes | Project version (semver). |
services |
object |
Yes | Service configuration block. |
services.data
| Field | Type | Default | Description |
|---|---|---|---|
enabled |
boolean |
false |
Enable the data service. |
dialect |
string |
— | Use mssql for a SQL database in Fabric. Required when Data is enabled. |
path |
string |
— | Data package directory relative to the project root, such as packages/data. Flat templates can use rayfin/data. |
buildCommand |
string |
— | Build command for the configured data package. |
services.auth
| Field | Type | Default | Description |
|---|---|---|---|
enabled |
boolean |
false |
Enable the auth service. |
expiryInMinutes |
number |
— | JWT token expiry in minutes. |
customClaims |
Record<string, string> |
— | Custom claims added to issued JWTs. |
scopes |
string[] |
— | OAuth scopes (for example, ["read:data", "write:data"]). |
refreshToken.lifetimeInDays |
number |
— | Refresh token lifetime in days. |
allowedRedirectUris |
string[] |
["http://localhost:5173"] |
Allowed redirect URIs for auth callbacks. |
services.auth.password
| Field | Type | Default | Description |
|---|---|---|---|
enabled |
boolean |
true |
Enable email and password authentication for local development |
services.auth.fabric
| Field | Type | Default | Description |
|---|---|---|---|
enabled |
boolean |
false |
Enable Fabric brokered authentication (Microsoft Entra ID SSO). |
externalEntraExchange |
boolean |
— | Enable direct delegated Entra token exchange and external-parent-host authentication when supported by the target environment. |
services.staticHosting
| Field | Type | Default | Description |
|---|---|---|---|
enabled |
boolean |
false |
Enable static content hosting. |
path |
string |
— | Frontend package directory relative to the project root. |
root |
string |
— | Legacy frontend root used by flat configurations. |
folder |
string |
"dist" |
Directory containing built static assets relative to the resolved frontend path. |
buildCommand |
string |
— | Shell command to run before packaging (for example, npm run build). |
indexDocument |
string |
— | Default document served for the root path (for example, index.html). |
Tip
All string values support environment variable interpolation with ${VAR} and ${VAR:-default} syntax. Variables are resolved from rayfin/.env and the shell environment.
rayfin/.env
The rayfin/.env file contains the active runtime and deployment values and supplies values to rayfin.yml through interpolation. The CLI writes framework-neutral RAYFIN_PUBLIC_* values for the active backend. Only variables with that prefix are projected into generated frontend environment files. Never put secrets in RAYFIN_PUBLIC_* variables.
Keep rayfin/.env out of source control. Use rayfin/.env.example to document expected variables with placeholders.
rayfin/.deployments.json
The deployment registry records backend URLs, hosting URLs, item IDs, and workspace IDs for your project's deployments. It isn't a frontend environment file. Keep it out of source control. Use npx rayfin up list to list recorded deployments and npx rayfin up switch <name> to switch the active deployment and regenerate its environment values.
rayfin/tsconfig.json
Templates provide TypeScript configuration for their layout. Workspace packages have their own configurations and project references; flat templates can compile entities through rayfin/tsconfig.json. Preserve the scaffold's references and use its build and type-check scripts rather than assuming a single root compilation.
Data model files
Keep runtime registration and client-facing types aligned for your chosen layout.
Workspace entities and shared contracts
In Universal App, files under packages/data/src/ define decorated entity classes. Register the runtime classes in the schema array exported by packages/data/src/index.ts.
Maintain matching record interfaces and the UniversalAppSchema type in packages/shared/src/index.ts. The frontend imports this contract from @rayfin-app/shared instead of importing decorated backend classes.
Flat-template entities
In a flat template, rayfin/data/*.ts defines entities and rayfin/data/schema.ts maps entity names to types for client.data.<Entity>. Follow the registration mechanism supplied by that template.
Generated artifacts
rayfin/.temp/
The rayfin/.temp/ folder contains generated backend artifacts that are created when you run the development server. If the backend appears to be using stale schema or configuration, stop and restart the dev stack to regenerate these files.
Important
Don't commit the .temp/ folder to your repository. Add it to your .gitignore file.
Frontend structure
The default frontend is in packages/frontend/src/. Flat templates can use root src/. The services.staticHosting.path setting identifies the frontend package.
Active environment and framework mapping
rayfin dev and rayfin up generate framework-specific .env.local values from rayfin/.env. For a nested frontend, the file is written under services.staticHosting.path, such as packages/frontend/.env.local; flat projects use the project root.
Source in rayfin/.env |
Vite output in .env.local |
Next.js output in .env.local |
|---|---|---|
RAYFIN_PUBLIC_API_URL |
VITE_RAYFIN_API_URL |
NEXT_PUBLIC_RAYFIN_API_URL |
RAYFIN_PUBLIC_PUBLISHABLE_KEY |
VITE_RAYFIN_PUBLISHABLE_KEY |
NEXT_PUBLIC_RAYFIN_PUBLISHABLE_KEY |
RAYFIN_PUBLIC_ITEM_ID |
VITE_FABRIC_ITEM_ID |
NEXT_PUBLIC_FABRIC_ITEM_ID |
RAYFIN_PUBLIC_WORKSPACE_ID |
VITE_FABRIC_WORKSPACE_ID |
NEXT_PUBLIC_FABRIC_WORKSPACE_ID |
RAYFIN_PUBLIC_PORTAL_URL |
VITE_FABRIC_PORTAL_URL |
NEXT_PUBLIC_FABRIC_PORTAL_URL |
Edit the source values in rayfin/.env, not the generated file. To regenerate without deploying:
npx rayfin env --framework vite
Use --framework nextjs or --framework plain for other supported mappings. Use --output <dir> to choose an output directory or --show to inspect the public mapping without writing. Keep generated .env.local files out of source control.
Migrate an older environment layout
Older projects might contain .env.fabric or .env.fabric-<workspace> files. These files aren't the active environment files in the current layout. Run npx rayfin up to use the current environment workflow. Review any migration messages, and copy custom values into rayfin/.env as needed. The deployment registry replaces per-workspace environment files. Don't configure new apps to depend on them.