Architecture - camellia-app/camellia GitHub Wiki

Camellia is a browser extension build with latest versions of React, Redux and TypeScript.

Supported runtimes

Runtimes provide unique low-level extension APIs for interacting with browser like bookmarks and storage APIs. Currently, Camellia supports only 3 runtimes:

We do not focus on supporting very old browsers. We support browsers whose versions are 1 year old or newer. We may drop support of old browsers in the extension via limiting minimum version in manifest.json file. We do not accept bug reports from such old browsers.

Note: Safari currently is not supported. See issue #497.

Internal APIs

We use abstraction layers to hide implementation details of some low-level APIs such as extension APIs and Web APIs.

For example, Storage API may have a lot of different implementations: local storage, storage that syncs between installations, IndexedDB, also first two examples have different implementations for different runtimes: Chromium and WebExtensions. But all these implementations have unified public interface (API) for storage that makes it easier to maintain the codebase and helps our APIs to be predictable and easy to understand.

React application interacts with all these APIs via hooks.

CSS

For CSS we use vanilla CSS and CSS Modules.

We do not pass arbitrary CSS properties via style attribute. When we need to pass some variable from JavaScript (React) to CSS, we use CSS custom properties (variables).

We use dts-css-modules-loader to generate .d.ts files for our CSS modules to ensure we use class names that exist and there are no typos.

We also define these CSS properties globally for all HTML elements:

  • all: unset instead of Reset CSS and Normalize.css to make sure all elements behave like plain <div> elements.
  • Because all: unset resets all elements to be inline elements, but it's rare case when we need inline elements in our layout, that's why we also add display: block to all elements.
  • box-sizing: border-box on all elements to prevent unexpected layout bugs.

Icons

We use Google's Material Icons. Package @material-design-icons/svg provides these icons as SVGs.

Favicons

Chromium platform

In Chromium browsers we use Favicon API (available in Manifest V3).

Other platforms

Currently, there are no APIs in WebExtensions platform (Firefox) to access favicons stored in browser. That's why we use proxy server for favicons until browser vendors will release official API for accessing cached favicons. There are tasks in official bug trackers, we track them in issue #39.

As temporary solution we use our own Website Icons Proxy. This is a Cloudflare Worker - a cloud function that runs on top of Cloudflare network written in TypeScript. This is special proxy that allows Camellia to download and cache favicons in Cloudflare CDN, so it works blazing fast and does not expose anything about Camellia users to websites. We build URLs like https://website-icons.camellia.app/favicon?domain=google.com and this URL may be safely used in <img> HTML element or url() CSS function.

Please note that Website Icons Proxy instance deployed by Camellia maintainers (located at https://website-icons.camellia.app) is designed to work only with Camellia, it does not have any SLAs, it does not promise backward compatibility and does not give your any guarantees at all, so you should not use it for your projects. It's open source project, you should deploy your own instance of Website Icons Proxy.

Internationalization

Please read "Languages" page to get know what languages we support.

Our translation files are fully compatible with the format used by Chromium and WebExtensions platforms. It would be good to read an article "Internationalization" on MDN to understand how they work in WebExtensions.

Performance Measurement

To provide better experience to our users we collect some performance metrics to understand how smooth Camellia works and to detect any performance degradations. We use Sentry for that purpose.

Currently, we track performance of these things:

  1. How long it takes to open Camellia and see what happens during the process,
  2. How long React hook is running,
  3. And also we measure some browser events, like clicking a folder bookmark to open popup.

Resources:

⚠️ **GitHub.com Fallback** ⚠️