diff --git a/custom-words.txt b/custom-words.txt index 668bef9f3..6ac7d3dba 100644 --- a/custom-words.txt +++ b/custom-words.txt @@ -14,6 +14,7 @@ hotfixes inet IntelliJ Iterm +incentivizing jslib jumpcloud keychain diff --git a/docs/architecture/adr/0022-team-owned-libs.md b/docs/architecture/adr/0022-team-owned-libs.md new file mode 100644 index 000000000..f9c6493f9 --- /dev/null +++ b/docs/architecture/adr/0022-team-owned-libs.md @@ -0,0 +1,63 @@ +--- +adr: "0022" +status: In progress +date: 2023-01-09 +tags: [clients] +--- + +# 0022 - Team-owned libs + + + +## Context and Problem Statement + +Historically, much of the feature logic of Bitwarden has existed within the `apps/` directories, +only being moved to `libs/` (usually `libs/common/` or `libs/angular/`) if it needed to be shared +between multiple clients. + +This pattern makes it more difficult for teams to independently manage code they own. + +## Considered Options + +- **Do nothing** - Keep our current pattern. +- **Template-driven forms** - Move functionality out of `apps/`, `libs/common/`, and `libs/angular/` + and move into libs that are smaller, feature-focused, and owned by a team. + +This is informed by [Nx](https://nx.dev/concepts/more-concepts/applications-and-libraries), a +monorepo tool: + +> A typical Nx workspace is structured into "apps" and "libs". This distinction allows us to have a +> more modular architecture by following a separation of concerns methodology, incentivizing the +> organization of our source code and logic into smaller, more focused and highly cohesive units. + +
+A common mental model is to see the application as "containers" that link, bundle and compile functionality implemented in libraries for being deployed. As such, if we follow a 80/20 approach: + + - place 80% of your logic into the libs/ folder + - and 20% into apps/ + +Note, these libraries don’t necessarily need to be built separately, but are rather consumed and +built by the application itself directly. Hence, nothing changes from a pure deployment point of +view. + +
+ +## Decision Outcome + +Chosen option: **Team-owned libs** + +### Positive Consequences + +- **Clear public API** - Each team can decide what is public and private within their library. This + prevents teams from relying on code that is meant to be internal. +- **More team autonomy** - +- **Easier to share code between apps** - +- **Clearer dependency graph** - It will be easier to inspect which teams are relying internal and + external dependencies. +- **Simplified code ownership** - +- **Incremental builds** - + +### Negative Consequences + +- **Managing circular dependencies** - +- **More boilerplate** - diff --git a/docs/architecture/clients/index.md b/docs/architecture/clients/index.md index 6a53e495f..e520ce40c 100644 --- a/docs/architecture/clients/index.md +++ b/docs/architecture/clients/index.md @@ -10,18 +10,65 @@ and a single [Git repository](https://github.com/bitwarden/clients). The mono-repository root directory contains three main folders. -- `apps` - Our different application specific code, consists of `web`, `browser`, `desktop` and +- `apps`: Our different application specific code, consists of `web`, `browser`, `desktop` and `cli`. -- `bitwarden_license` - Bitwarden Licensed version of the web vault. -- `libs` - Shared code between the different applications. - -`libs` contains the following projects. - -- `Common` - Common code shared between all the clients including CLI. -- `Angular` - Angular specific code used by all the visual clients. -- `Components` - Angular Components Library. -- `Node` - Used to be shared code for CLI and Directory Connector CLI, but since directory connector - no longer uses the same version of libs this module is deprecated. +- `bitwarden_license`: Bitwarden Licensed version of the web vault. +- `libs`: Shared code between the different applications. + +## Libs + +Historically, much of the feature logic of Bitwarden has existed within the `apps/` directories, +only being moved to `libs/` (usually `libs/common/` or `libs/angular/`) if it needed to be shared +between multiple clients. + +We are attempting to move to a more modular architecture by creating additional libs that are more +feature-focused and which more accurately convey team code ownership. + +- `common`: Common code shared between all the clients including CLI +- `angular`: Low-level Angular utilities used by all the visual clients +- `node`: Used to be shared code for CLI and Directory Connector CLI, but since directory connector + no longer uses the same version of libs this module is deprecated +- `admin-console`: Code owned by the Admin Console team +- `auth`: Code owned by the Auth team +- `billing`: Code owned by the Billing team +- `components`: Angular implementation of the Bitwarden design system + [See more.](https://components.bitwarden.com/) +- `exporter`: Code related to exporting; owned by the Tools team +- `importer`: Code related to importing; owned by the Tools team +- `platform`: Code owned by the Platform team +- `vault`: Code owned by the Vault team + +### Background + +More on this approach can be found in the +[Nx documentation](https://nx.dev/concepts/more-concepts/applications-and-libraries): + +> place 80% of your logic into the `libs/` folder and 20% into `apps/` + +We are doing the opposite of this right now. The code that remains in `apps/` should be primarily +concerned with bootstrapping the application and consuming and configuring code exported from +`libs/`. Over time, code not meeting this criteria should be moved from `apps/` to `libs/`. + +Any code in the `apps/` that doesn't have a tight coupling with the client can be moved into a lib: +if an exported member is wholly dependent on other libs but not `apps/`, it can likely be moved to a +lib itself. (More concretely, this bars components that rely on global client-specific CSS — but not +components built with Tailwind and the CL — from being included in a lib) + +> Having a dedicated library project is a much stronger boundary compared to just separating code +> into folders, though. Each library has a so-called "public API", represented by an index.ts barrel +> file. This forces developers into an "API thinking" of what should be exposed and thus be made +> available for others to consume, and what on the others side should remain private within the +> library itself. + +An existing example of this pattern is `@bitwarden/components`: + +- It is consumed by multiple apps and other libs +- It manages a clear public and private API boundary through its barrel file +- Code ownership is clear — the CL team only owns the files within `libs/components` +- The CL team can make independent decisions around internal folder structure and code style + +As part of this process, we are also investigating utilizing additional tooling (such as Nx) to make +creating new libs on the fly easier. ## Package Diagram