ente/web/docs/dependencies.md
Manav Rathi 18cc16bcc0
Use preferred casing of Wasm
From webassembly.org

> WebAssembly (abbreviated _Wasm_) is ...
2025-02-03 11:15:00 +05:30

10 KiB

Dependencies

Dev

These are some global dev dependencies in the root package.json. These set the baseline for how our code be in all the workspaces in this (yarn) monorepo.

They also need some support packages, which come from the leaf @/build-config package:

The root package.json also has a convenience dev dependency:

  • concurrently for spawning parallel tasks when we invoke various yarn scripts.

Cryptography

We use libsodium for our cryptography primitives. We use its WebAssembly target, accessible via JavaScript wrappers maintained by the original authors of libsodium themselves - libsodium-wrappers.

More precisely, we use the sumo variant, "libsodium-wrappers-sumo", since the standard variant does not provide the crypto_pwhash_* functions.

Meta frameworks

Next.js

Next.js (package: next) provides the meta framework for both the photos and the auth app, and also for some of the sidecar apps like accounts and cast.

We use a limited subset of Next.js. The main thing we get out of it is a reasonable set of defaults for bundling our app into a static export which we can then deploy to our webserver. In addition, the Next.js page router is convenient. Overall our apps can be described as regular React SPAs, and are not particularly tied to Next.js.

Vite

For some of our newer code, we have started to use Vite. It is likely the future (both generally, and for our code) since Next.js is becoming less suitable for SPAs and static SSR with their push towards RSC and dynamic SSR.

UI

React

React (package: react) is our core framework. We also import its a sibling react-dom package that renders JSX to the DOM.

Note

We need to repeat the dependency on react and its siblings in multiple package.jsons to avoid the unmet peer dependency warnings printed by yarn. Ideally, the react dependencies can be specified just in the @/base package.

MUI and Material Icons

We use MUI's @mui/material as our base React component library (In our code and documentation, we use the name "MUI" to refer to the the combination of both MUI's "Material UI" and "System" packages that we use).

MUI uses Emotion as its preferred CSS-in-JS library, for which we need to install install two Emotion packages (@emotion/react and @emotion/styled) as peer dependencies.

We also use MUI's @mui/material-icons package, which provides Material icons exported as React components (a SvgIcon).

Note

For a similar reason as with react,

  • the @mui/material dependency is also repeated at more places - the one in @/base is the canonical one.
  • we need to add an explicit dependency to mui/system in @/new even though we don't directly depend on it.

Date pickers

@mui/x-date-pickers is used to get a date/time picker component. This is the community version of the DateTimePicker component provided by MUI.

dayjs is used as the date library that that @mui/x-date-pickers will internally use to manipulate dates.

Translations

For showing the app's UI in multiple languages, we use the i18next, specifically its three components

  • i18next: The core i18next library.
  • react-i18next: React specific support in i18next.
  • i18next-http-backend: Adds support for initializing i18next with JSON file containing the translation in a particular language, fetched at runtime.

Note that inspite of the "next" in the name of the library, it has nothing to do with Next.js.

For more details, see translations.md.

Font

Inter Variable (with support for weights 100 - 90) is used as the primary font, via @fontsource-variable/inter.

UI components

  • react-window is used for lazy-ily rendering large lists of dynamically created content, each item being of a variable height. It is usually used in tandem with its sibling package, react-virtualized-auto-sizer which allows the lazy list to resize itself automatically to fill the entire remaining space available in the container.

  • formik provides an easier to use abstraction for dealing with form state, validation and submission states when using React.

  • react-select is used for search dropdowns.

  • react-otp-input is used to render a segmented OTP input field for 2FA authentication.

Utilities

  • comlink provides a minimal layer on top of web workers to make them more easier to use.

  • idb provides a promise API over the browser-native IndexedDB APIs.

    For more details about IDB and its role, see storage.md.

  • zod is used for runtime typechecking (e.g. verifying that API responses match the expected TypeScript shape).

  • nanoid is used for generating unique identifiers. For one particular use case, we also need uuid for UUID v4 generation.

  • bs58 is used for base-58 conversion (used for encoding the collection key to use as the hash in the share URL).

  • debounce and its promise-supporting sibling pDebounce are used for debouncing operations (See also: [Note: Throttle and debounce]).

  • zxcvbn is used for password strength estimation.

Media

  • ffmpeg.wasm is used to run FFmpeg in the browser using WebAssembly (Wasm). Note that this is substantially slower than native ffmpeg (the desktop app can, and does, bundle the faster native ffmpeg implementation too).

  • ExifReader is used for Exif parsing.

  • jszip is used for reading zip files in the web code (Live photos are zip files under the hood). Note that the desktop app uses also has a ZIP parser (that one supports streaming).

  • file-type is used for MIME type detection. We are at an old version 16.5.4 because v17 onwards the package became ESM only - for our limited use case, the custom Webpack configuration that it'd entail is not worth the upgrade.

  • heic-convert is used for converting HEIC files (which browsers don't natively support) into JPEG. For (much more) details, see heic.md.

Photos app specific

  • react-dropzone is a React hook to create a drag-and-drop input zone. Note that we pin to the last version in the 14.2 series, since if we use 14.3 onwards (I tested till 14.3.5) then we are unable to get back a path from the file by using the webUtils.getPathForFile function provided by Electron.

  • sanitize-filename is for converting arbitrary strings into strings that are suitable for being used as filenames.

  • chrono-node is used for parsing natural language queries into dates for showing search results.

  • matrix is mathematical matrix abstraction by the machine learning code. It is used alongwith similarity-transformation during face alignment.

  • react-top-loading-bar is used for showing a progress indicator for global actions (This shouldn't be used always, it is only meant as a fallback when there isn't an otherwise suitable place for showing a local activity indicator).

Auth app specific

  • otpauth is used for the generation of the actual OTP from the user's TOTP/HOTP secret.

  • However, otpauth doesn't support steam OTPs. For these, we need to compute the SHA-1, and we use the same library, jssha that otpauth uses since it is already part of our bundle (transitively).