Web Setup Instructions
July 10, 2026 ยท View on GitHub
Prerequisites
Web-Specific Prerequisites
-
Install mkcert and Setup HTTPS
- Install
mkcert:brew install mkcertfollowed bynpm run setup-https. If you are not using macOS, follow the instructions here.
- Install
-
Configure Local Hosts
- Create a host entry in your local hosts file,
/etc/hostsfor dev.new.expensify.com pointing to localhost:
127.0.0.1 dev.new.expensify.com - Create a host entry in your local hosts file,
Recommended Node Setup
In order to have more consistent builds, we use a strict node and npm version as defined in the package.json engines field and .nvmrc file. npm install will fail if you do not use the version defined, so it is recommended to install node via nvm for easy node version management. Automatic node version switching can be installed for zsh or bash using nvm.
Configuring HTTPS
The Rspack development server now uses https. If you're using a mac, you can simply run npm run setup-https.
If you're using another operating system, you will need to ensure mkcert is installed, and then follow the instructions in the repository to generate certificates valid for dev.new.expensify.com and localhost. The certificate should be named certificate.pem and the key should be named key.pem. They should be placed in config/rsbuild.
If you already generated certificates before the Webpack โ Rsbuild migration, they're now in the wrong place (config/webpack, which no longer exists). Just re-run npm run setup-https to regenerate them in config/rsbuild, or move the existing files: mv config/webpack/{key,certificate}.pem config/rsbuild/.
Running the Web App
Development Server
- To run the development web app:
npm run web - Changes applied to Javascript will be applied automatically via Rsbuild as configured in
config/rsbuild/rsbuild.config.ts
Production Build
To build and run the production web build locally:
# 1. Set USE_WEB_PROXY environment variable in .env.production
USE_WEB_PROXY=true
# 2. Build the production bundle
npm run build
# 3. Run the distribution server
npm run web:dist
The web:dist command starts both the proxy server (port 9000) and web server (port 8080) concurrently. Access the application at http://localhost:8080
Environment Variables
Creating an .env file is not necessary. We advise external contributors against it. It can lead to errors when variables referenced here get updated since your local .env file is ignored.
Key Variables for Web Development
NEW_EXPENSIFY_URL- The root URL used for the websiteSECURE_EXPENSIFY_URL- The URL used to hit the Expensify secure APIEXPENSIFY_URL- The URL used to hit the Expensify APIEXPENSIFY_PARTNER_NAME- Constant used for the app when authenticating.EXPENSIFY_PARTNER_PASSWORD- Another constant used for the app when authenticating. (This is OK to be public)PUSHER_APP_KEY- Key used to authenticate with Pusher.comUSE_WEB_PROXYโ ๏ธ- Used in web development, it starts a server along the local development server to proxy requests to the backend. External contributors should set this totrueotherwise they'll have CORS errors. If you don't want to start the proxy server set this explicitly tofalse
Optional Performance Variables
CAPTURE_METRICS(optional) - Set this totrueto capture performance metrics and see them in Flipper. See PERFORMANCE.md for more informationONYX_METRICS(optional) - Set this totrueto capture even more performance metrics and see them in Flipper. See React-Native-Onyx#benchmarks for more informationUSE_WDYR- Flag to turnWhy Did You Rendertesting on or off
If your changes to .env aren't having an effect, try
rm -rf .rock, then re-runnpm run web
Testing on Browsers in Simulators and Emulators
The development server is reached through the HTTPS protocol, and any client that access the development server needs a certificate.
You create this certificate by following the instructions in Configuring HTTPS of this readme. When accessing the website served from the development server on browsers in iOS simulator or Android emulator, these virtual devices need to have the same certificate installed.
All Platforms Setup
If you want to set up both iOS and Android simulators at once:
- Run
npm run setupNewDotWebForEmulators allornpm run setupNewDotWebForEmulators - Check if the iOS flow runs first and then Android flow runs.
- Let the script execute till the message
๐ Done!.
Debugging
Browser DevTools
To make it easier to test things in web, we expose the Onyx object to the window, so you can easily do Onyx.set('bla', 1).
Build Profiling (Rspack)
To time, profile, and analyze the Rspack build itself (as opposed to the app's runtime), set the RSPACK_PROFILE environment variable on any build or dev server command:
# Core build process timing (recommended)
RSPACK_PROFILE=OVERVIEW npm run build
# Every trace event - much larger output, only for deep investigation
RSPACK_PROFILE=ALL npm run build
This generates a .rspack-profile-<timestamp>-<pid>/rspack.log file (JSON Lines) with per-loader/per-plugin timing for the build. To generate a Perfetto-format trace instead, set RSPACK_TRACE_LAYER=perfetto:
RSPACK_TRACE_LAYER=perfetto RSPACK_PROFILE=OVERVIEW npm run build
Open the resulting .rspack-profile-<timestamp>-<pid>/rspack.pftrace file at ui.perfetto.dev to visualize it. For bundle size (as opposed to build time) analysis, use npm run analyze-packages, which runs Rsdoctor against the build output and opens an interactive report covering bundle composition, duplicate packages, and per-loader/per-plugin timing.
Release Profiling for Web
- Install the necessary packages:
npm i - Run your web app in production mode
- Upon completion, the generated source map can be found at:
dist/merged-source-map.js.map - To symbolicate traces:
npm run symbolicate-release:web
Recording Traces
- Launch the app in production mode.
- Navigate to the feature you wish to profile.
- Initiate the profiling session by pressing
cmd+dto open the menu and selectingUse Profiling. - Close the menu and interact with the app.
- After completing your interactions, press
cmd+dagain and select to stop profiling. - You will be presented with a
Shareoption to export the trace, which includes a trace file (Profile<app version>.cpuprofile) and build info (AppInfo<app version>.json).
How to Symbolicate Trace Records
- You have two files:
AppInfo<app version>.jsonandProfile<app version>.cpuprofile - Place the
Profile<app version>.cpuprofilefile at the root of your project. - If you have already generated a source map from the steps above for this branch, you can skip to the next step. Otherwise, obtain the app version from
AppInfo<app version>.jsonswitch to that branch and generate the source map as described.
IMPORTANT: You should generate the source map from the same branch as the trace was recorded.
- Use the following command to symbolicate the trace:
npm run symbolicate-release:web - A new file named
Profile_trace_for_<app version>-converted.jsonwill appear in your project's root folder. - Open this file in your tool of choice:
- SpeedScope (https://www.speedscope.app)
- Perfetto UI (https://ui.perfetto.dev/)
- Google Chrome's Tracing UI (chrome://tracing)
Troubleshooting
CORS Errors
If you are running into CORS errors like (in the browser dev console):
Access to fetch at 'https://www.expensify.com/api/BeginSignIn' from origin 'http://localhost:8080' has been blocked by CORS policy
You probably have a misconfigured .env file - remove it (rm .env) and try again
General Issues
- If you are having issues with Getting Started, please reference React Native's Documentation
- Make sure you have the correct Node version installed as specified in
.nvmrc - Ensure HTTPS is properly configured if you're having certificate issues
Note: Expensify engineers that will be testing with the API in your local dev environment please refer to these additional instructions.