Coming from this proposal
Strategy:
Expensify is striving to move faster and be more inclusive in a competitive landscape. Adopting modern JavaScript patterns can help developers write clearer code faster = making our open-source code more accessible to outside contributors.
Background:
- Current coding guidelines prohibit using
async/await in application code (enforced by ESLint), requiring developers to use promise chaining (.then/.catch) instead for asynchronous calls.
- The app’s architecture emphasizes “fire-and-forget” API calls from UI components, meaning most calls don’t need to be awaited. However, some parts of the system (e.g. GitHub Actions workflows, tests, and Node scripts) do require running async steps in sequence. In these contexts, chained promises often lead to deeply nested code, which is why we already allow
async/await there.
- Industry-wide,
async/await has been standard since ES2017 and is now the dominant style for async code await vs .then in open-source TypeScript). Both patterns are compatible and can coexist in the same codebase, even the MDN documentation uses them together on this page.
- Our app is open source, so aligning our conventions with the broader TypeScript community makes it easier for outside developers to contribute.
Problem:
When code requires sequential asynchronous flows, developers must use chained .then/.catch, in many cases the code becomes fragmented and harder to read, slowing reviews and increasing maintenance costs.
src/libs/fileDownload/index.android.ts is a clear example of how chaining obscures intent async/await version for comparison
Solution:
Allow async/await in our application code for cases where asynchronous operations need to happen in sequence.
This is not a proposal to migrate the entire codebase, promise chaining will remain the default pattern. In practice, this means:
- Permit the use of
async/await in app code for flows that are inherently sequential. Developers can then write those sequences in a straight-line style instead of nesting multiple .then() callbacks.
- Update our coding standards (e.g. the STYLE.md guide) to document when and how
async/await should be used, ensuring consistency and preventing misuse.
Coming from this proposal
Strategy:
Expensify is striving to move faster and be more inclusive in a competitive landscape. Adopting modern JavaScript patterns can help developers write clearer code faster = making our open-source code more accessible to outside contributors.
Background:
async/awaitin application code (enforced by ESLint), requiring developers to use promise chaining (.then/.catch) instead for asynchronous calls.async/awaitthere.async/awaithas been standard since ES2017 and is now the dominant style for async code await vs .then in open-source TypeScript). Both patterns are compatible and can coexist in the same codebase, even the MDN documentation uses them together on this page.Problem:
When code requires sequential asynchronous flows, developers must use chained
.then/.catch, in many cases the code becomes fragmented and harder to read, slowing reviews and increasing maintenance costs.src/libs/fileDownload/index.android.ts is a clear example of how chaining obscures intent async/await version for comparison
Solution:
Allow
async/awaitin our application code for cases where asynchronous operations need to happen in sequence.This is not a proposal to migrate the entire codebase, promise chaining will remain the default pattern. In practice, this means:
async/awaitin app code for flows that are inherently sequential. Developers can then write those sequences in a straight-line style instead of nesting multiple.then()callbacks.async/awaitshould be used, ensuring consistency and preventing misuse.