Main Content

Best Practices for Authoring Web Apps

R2026b

MATLAB® 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 groot properties, such as ScreenSize and MonitorPositions, 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 Position values 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 figure or uifigure from 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, and inputdlg with uialert, uiconfirm, or uiprogressdlg.

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.requiredFilesAndProducts to 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 ctfroot or locate them with which, 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.webAppArchive function.

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 isdeployed to 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\Desktop or /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 uigetfile to upload files from the client to the server.

  • Use uiputfile to 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:

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-config to review and set session UI keys, such as app_session_full_screen and app_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_ancestors and allowed_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

AreaCommon IssueBest Practice
LayoutControls overlap or clipUse uigridlayout and container-based layout
Screen metricsIncorrect sizing logicAvoid groot screen properties for layout
WindowsMulti-window flows failSingle-window UI with tabs and panels
DialogsDesktop dialog boxes failUse uialert, uiconfirm, uiprogressdlg
FilesFile I/O fails when using client-side pathsUse uigetfile and uiputfile, treat I/O as server-side
ConcurrencyUsers overwrite outputsUse tempname and per-session storage
ExportPrinting or export failsAvoid unsupported print/export workflows
Embeddingiframe blockedConfigure 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 groot screen properties for layout

  • Does 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 ctfroot or which

  • Uses uigetfile and uiputfile for client exchange

  • Does 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_ancestors and related keys are configured

  • App 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

See Also

Topics