Best Practices for Authoring Web Apps
R2026bMATLAB® Web App Server™ runs your app code on a server and renders the user interface in a web browser. Because execution is on the server side, some desktop behaviors are not available, and some functions return server information rather than client information. Use the guidance in this topic while designing and coding your app to reduce layout issues, file access problems, and unsupported workflow errors.
For general guidance on writing code that works correctly after compilation, see Write Deployable MATLAB Code.
UI and Graphics
Avoid Server Screen Assumptions
In deployed web apps, groot screen properties describe the
server display environment, not the client browser window.
Best practice:
Do not use
grootproperties, such asScreenSizeandMonitorPositions, to compute layout decisions.
Support User-Driven Resizing
End users can resize the browser window or switch the session to full screen, so your app layout must respond smoothly to size changes.
Best practice:
Use layout managers, such as
uigridlayout, instead of fixed-pixel positioning.Use App Designer resize behavior instead of manually repositioning components.
Avoid hard-coded pixel
Positionvalues for controls.If you need custom behavior on resize, follow App Designer resizing guidance rather than manually repositioning components. For details, see Manage Resizable Apps in App Designer.
Windows and Dialogs
Avoid Creating Multiple Windows
Deployed web apps do not support multi-window workflows. App Designer creates the
app window as a uifigure. Creating any additional window by
calling figure or uifigure in your code is
not supported.
Best practice:
Do not call
figureoruifigurefrom your app code.For multi-view workflows, use tabs, panels, or other in-window navigation patterns.
Use Supported In-App Dialogs
Separate-window dialog boxes used in desktop apps are not supported in deployed web apps.
Best practice:
Replace dialog box workflows based on
msgbox,errordlg,questdlg, andinputdlgwithuialert,uiconfirm, oruiprogressdlg.
Files, Paths, and Permissions
Include Required Files in Deployable Archive
MATLAB
Compiler™ packages app content into a deployable archive
(.ctf file). An application that compiles successfully might
fail at runtime if the archive does not include required dependencies.
Best practice:
Use MATLAB Projects to organize your app and review dependencies before packaging. For details, see Create Projects.
Rely on compiler dependency analysis, but treat it as a starting point. Review the dependency list early when preparing the app for deployment.
During development, use
matlab.codetools.requiredFilesAndProductsto identify required files and products.Explicitly include non-MATLAB files and other required assets, such as data files, configuration files, DLLs, and other resources, in the deployable archive. Add files to the package in the compiler workflow. Do not assume that they will be discovered automatically.
To access packaged files at runtime, use
ctfrootor locate them withwhich, rather than relying on the current folder or absolute paths.To create the archive with your intended build inputs and included files, package it using the Web App Compiler app or the
compiler.build.webAppArchivefunction.
Understand Where File Operations Run
This section covers files that cannot be packaged in the deployable archive, such as server-side databases, shared output folders, or configuration files managed outside the app.
Deployed web apps run on the server. When your app reads or writes a file, it accesses the server file system, not the user's local computer. Many environment queries also return server information rather than client information.
When the app is deployed, MATLAB Web App Server runs your code under a dedicated worker account that has minimal file system permissions by default. Your app can only read or write locations that the server administrator has explicitly granted access to.
Best practice:
Use
isdeployedto select appropriate paths for development and deployment. In desktop MATLAB, use local test paths. When deployed, use server-side paths that the worker account can access.Avoid logic that assumes the user's local folders are accessible to your code. For example, do not build paths like
C:\Users\name\Desktopor/Users/name/Downloads, and do not expect a path the user sees in their browser to exist on the server.For most output workflows, write to the current working directory (
pwd), which is unique to each app session and is automatically deleted when the session ends. For outputs that must persist beyond the session or be shared across sessions, use a server-writable location and document the required permissions.Use unique filenames and per-session folders to prevent collisions when multiple users run the app at the same time.
Example:
if isdeployed dataPath = "/mwas/shared/data"; else dataPath = fullfile(pwd, "testdata"); end
Use File Selection Dialog Boxes for Client Upload and Download
Web apps can use browser-based file transfer to let users upload files to the
server or download files to their local machines. File selection dialog box behavior differs between web apps and
desktop apps. For example, you cannot specify the default path or file name for
uiputfile in a web app. In addition, you cannot set the downloaded file
path programmatically. The browser handles the download and saves the file, using the end
user's chosen file name and location.
Best practice:
Use
uigetfileto upload files from the client to the server.Use
uiputfileto download files from the server to the client.
Example:
[file, folder] = uigetfile({"*.csv;*.xlsx","Data files"}, "Select data file");
if isnumeric(file)
return
end
fullpath = fullfile(folder, file);
T = readtable(fullpath);Avoid Repeated Downloads
In a web context, writing in a loop can trigger repeated downloads.
Best practice:
Prepare your output content first, then write once.
Example:
[file, folder] = uiputfile("results.csv", "Save results"); if isnumeric(file) return end f = fullfile(folder, file); % Prepare data first, then write once writetable(app.ResultsTable, f);
Prevent Multi-User Collisions
If multiple users run the app and your code writes to an explicitly shared location with a fixed filename, collisions can cause overwrites and intermittent failures. The default working directory is unique to each app session, so this type of collision can occur only when you specify shared output paths.
Best practice:
Use per-session unique filenames such as
tempname.Avoid shared, fixed output names unless you explicitly coordinate access.
Example:
% Shared location — use unique filename per session outFile = fullfile(app.SharedOutputFolder, [tempname ".mat"]); save(outFile, "data");
Verify Worker Account Permissions
Apps that read or write to static server paths can fail after deployment because the MATLAB Web App Server worker account lacks permission to access the required locations.
Best practice:
If you are an app author, identify the server folders, shares, or databases that your app must access and document the required read and write permissions in your deployment instructions.
If you are a server administrator, grant the worker account permissions to access the required locations. To learn which accounts run MATLAB Web App Server services, and to learn the default folder locations, see Service Information, Groups, and Folder Locations (MATLAB Web App Server).
Limitations and Unsupported Workflows
Review Unsupported Functionality Early
Some desktop workflows are not supported for deployed web apps —
for example, printing and export workflows such as
print, printpreview, and
exportapp.
Best practice:
Review MATLAB Web App Server limitations during development. For details, see Web App Limitations and Unsupported Functionality (MATLAB Web App Server).
Review MATLAB Compiler and MATLAB Compiler SDK™ limitations during development. For details, see Limitations for MATLAB Compiler and MATLAB Compiler SDK.
Confirm that the language features and toolboxes you use are supported for compilation. For details, see Support for MATLAB, Simulink, and Toolboxes.
Check for unsupported functions before packaging. For details, see Functions Not Supported for Compilation by MATLAB Compiler and MATLAB Compiler SDK.
Check your app code for patterns that commonly fail when deployed, such as use of hardcoded file paths, changing the working directory with
cd, or dynamically evaluated code strings.
Performance
Reduce Work During Startup
Web apps take longer to start than desktop apps because each app session must initialize an isolated environment. Prewarming workers reduces this delay, but does not eliminate it.
Best practice:
Avoid loading large datasets or creating complex plots in
StartupFcn. Show a lightweight initial view and load data on demand.Defer heavy computation until the user requests it.
Cache Results Per Session to Reduce Latency
Repeated expensive initialization inside callbacks increases latency and can look like a performance issue to the end user.
Best practice:
Cache derived results per session and reuse them across callbacks when the underlying data does not change during the session.
Server Configuration That Affects User Experience
Configure Session UI Behavior
Server configuration can change what end users see in an app session, which can affect app workflows and layout. Changes in what end users see can cause problems when the app relies on the session log being visible, or when full-screen mode exposes layout and scaling issues.
Best practice:
If you are an app author, do not rely on end users seeing the session log. If your app requires diagnostic feedback, display information and status in the app UI directly.
If you are an app author and your deployment might use full screen, test the app in both full-screen and non-full-screen sessions.
If you are a server administrator, use
webapps-configto review and set session UI keys, such asapp_session_full_screenandapp_session_show_footer.
Configure Embedding and Origins
Embedding a web app in an iframe is typically a deliberate deployment choice. If
you intend your app to be embedded, server configuration can affect whether the
embedded session loads and whether cross-origin interactions are allowed.
Best practice:
If you are an app author and your app will be embedded, test it in an embedded page early in development and document any assumptions or requirements.
If you are a server administrator, configure embedding and origin-related keys, such as
allowed_frame_ancestorsandallowed_event_origins.
Packaging
Use App Designer Apps
Build workflows for web app archives accept App Designer apps as input. You can
use either a binary format (.mlapp) or the plain-text
format (.m and .xml).
Best practice:
Author your web apps in App Designer and package them as web app archives.
If you use the plain-text app format for source control integration, note that you cannot create plain-text apps for Simulink models or custom UI components.
If you have an existing UI that is not an App Designer app, such as an M-file that creates a programmatic
uifigure, migrate the UI to App Designer before packaging it as a web app. You can move UI creation into App Designer and keep most application logic in separate functions or classes that the app calls.If you have an existing GUIDE app, migrate it to App Designer before packaging.
Best Practice Summary
| Area | Common Issue | Best Practice |
|---|---|---|
| Layout | Controls overlap or clip | Use uigridlayout and container-based
layout |
| Screen metrics | Incorrect sizing logic | Avoid groot screen properties for layout |
| Windows | Multi-window flows fail | Single-window UI with tabs and panels |
| Dialogs | Desktop dialog boxes fail | Use uialert, uiconfirm,
uiprogressdlg |
| Files | File I/O fails when using client-side paths | Use uigetfile and
uiputfile, treat I/O as server-side |
| Concurrency | Users overwrite outputs | Use tempname and per-session storage |
| Export | Printing or export fails | Avoid unsupported print/export workflows |
| Embedding | iframe blocked | Configure allowed_frame_ancestors |
Deployment Readiness Checklist
Before you deploy a web app, verify that it meets these conditions.
UI and Workflow
Uses layout containers, not fixed-pixel positioning
Does not rely on
grootscreen properties for layoutDoes not create additional figures or windows
Replaces desktop dialog boxes with supported in-app dialog boxes
Files and Data
All required files and assets are included in the deployable archive and accessible via
ctfrootorwhichUses
uigetfileanduiputfilefor client exchangeDoes not assume that client paths exist on the server
Uses per-session unique filenames and avoids shared output collisions
Avoids writing in a loop that triggers repeated downloads
Limitations and Export
Avoids unsupported printing and export patterns
Checks unsupported functionality list for any specialized features the app uses
Does not use unsupported functions
All required toolboxes support code generation
Server Configuration and Environment
Worker account has required permissions for server-side data locations
If embedding is required,
allowed_frame_ancestorsand related keys are configuredApp does not rely on the session footer or session log being visible, and it is tested in both full-screen and non-full-screen sessions when those modes can be used