Open-source project
safe-global/safe-wallet-monorepo avatar
safe-global/safe-wallet-monorepo

Safe{Wallet} monorepo puts the web and mobile wallets in one workspace

Safe{Wallet} – smart account wallet

595 stars681 forksTypeScriptGPL-3.0

At a glance

What is it?
Safe{Wallet} is the monorepo for the Safe multi-signature smart account wallet, holding a Next.js web app, an Expo and React Native mobile app, a shared Redux store and shared utilities under Yarn Workspaces, with Turbo driving the task runner. It suits a contributor to the Safe ecosystem or a team building on top of the wallet, and it is a large TypeScript codebase with a heavy toolchain.
Who is it for?
Adopt this repository when you are contributing to the Safe{Wallet} web or mobile application, or when you need the shared store and utility packages that both clients are built on. Do not adopt it as a self-hosted wallet deployment, since the product is a hosted application at app.safe.global and this repository is the client codebase.
Can I use it commercially?
Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

One workspace, two applications, two shared packages

The overview explains what the repository is and, more usefully, what it is not. Safe, formerly Gnosis Safe, is a multi-signature smart contract wallet for Ethereum and other EVM chains, requiring multiple signatures to execute transactions. This repository houses both the web and the mobile applications along with the shared packages, managed under a unified structure using Yarn Workspaces, and the stated benefit is that the monorepo setup simplifies dependency management and ensures consistent development practices across projects. The key components are five. apps/web is the Next.js web application and apps/mobile is the Expo and React Native mobile application. packages/store is the shared Redux store used by both platforms, packages/utils holds shared utilities and TypeScript types, and config/ holds the shared configuration files. The package manifest confirms the workspace globs, covering expo-plugins/*, apps/*, config/*, packages/* and tools/codemods/*. That last one is a hint about the codebase, since codemods exist for automated refactors across a tree this size.

Corepack and Yarn, then a plain install

The getting started section asks for the latest stable Node.js and Yarn 4.5.3 or later, and the way to get the right Yarn is corepack:

bash
corepack enable

and then just run:

bash
yarn

The README explains why that works. Corepack is a tool to help with managing versions of your package managers, and it exposes binary proxies for each supported package manager that, when called, will identify whatever package manager is configured for the current project, download it if needed, and finally run it. The initial setup is the familiar two steps, cloning the repository and then installing dependencies:

bash
git clone <repo-url>
cd monorepo
bash
yarn install

What is unusual is that there is no further setup step in the root README. Instead there is an important note pointing at the dedicated README files for the web application and the mobile application, with the web one described as a complete guide for the Next.js application and the mobile one as including iOS and Android setup. That is the right structure for a monorepo of this size, and it is also the thing to know before you start, because the two apps have genuinely different toolchains and a root-level instruction set would be misleading.

Turbo sits above Yarn, and the scripts are namespaced

The root package manifest shows the task runner pattern. The lint, type-check and test scripts are all turbo run calls with a trailing double dash, which passes the arguments through to each workspace, and there are four verify scripts backed by a node scripts/verify.mjs file, one of which takes a --changed flag so you can verify only what you touched. The prettier script checks formatting across the tree with the repository's own .prettierrc and .prettierignore, and the knip script runs an unused-export and unused-dependency check, with a web-specific variant. The postinstall script runs husky, which is why the .husky/ directory and .lintstagedrc.mjs at the root matter. Yarn workspaces commands are the documented way to act on one project, and the README is explicit about the syntax:

bash
yarn workspace <workspace-name> <script>
bash
yarn workspace <workspace-name> add <package-name>

The quick start examples name the actual workspaces, @safe-global/web and @safe-global/mobile, with the dev, start, test and storybook scripts on each. There is also a subtlety worth knowing, that Yarn treats commands containing a colon as global, so a command like cypress:open in a workspace can be run without the workspace prefix if no other workspace defines the same command.

The dependency set is where the ecosystem shows

The resolutions block in the root manifest is a long list of pinned versions, and reading it explains a lot about who this codebase serves. There are pins across axios, protobufjs, viem, stylus, webpack and postcss, a set of overrides on the Ledger hardware wallet packages, including @ledgerhq/context-module and the device signer kit for Ethereum with its ethers variant, and an override of the Zodiac module at @gnosis.pm/zodiac/ethers. Zodiac is the library that gives Safe accounts their module system, so its presence at a pinned version tells you the app depends on Safe account modules directly. There are also Yarn patch entries, the first being a patched @tamagui/image release, which is the mobile UI library. So the dependency graph is a record of the wallet's two hard edges, the EVM client stack and the hardware signer integrations, plus the mobile design system. The mobile app uses Tamagui and the web app uses Next.js and React, and the shared packages carry the parts both need so that a change to the transaction model is made once.

Tests, linting and the review checklist

The best practices section lists what a contribution is expected to pass before it is pushed. Use Yarn Workspaces commands for managing dependencies, ensure type-check, lint, prettier and tests pass, and follow the semantic commit message guidelines, with a pointer to conventionalcommits for the format. There is also a line for AI contributors, pointing at AGENTS.md for detailed guidelines, and the repository root confirms that file alongside CLAUDE.md, a .claude/ directory, a .agents/ directory and a .specify/ directory. The tooling list covers the quality gates in one place. Husky provides pre-commit hooks for linting, formatting and type-checking. ESLint and Prettier enforce coding standards and formatting. Jest is the unit testing framework and Cypress provides end-to-end testing for the web app. Storybook handles component documentation and development for the web app, and it has its own command, yarn workspace @safe-global/web storybook. Cypress runs in two modes, with cypress:open for interactive mode and cypress:run for headless mode, and the web README is said to cover Cypress E2E tests and Storybook in more detail.

The container image and the release path

The Dockerfile shows how the web app is built for deployment, and it is short. It starts from node:24-alpine and installs libc6-compat, git, python3, py3-pip, make, g++, libusb-dev, eudev-dev and linux-headers, then copies the whole repository and switches the working directory to apps/web. It enables corepack, sets the yarn httpTimeout to 300000, which is a large value needed because the dependency tree is big, and runs yarn install --immutable followed by yarn after-install. The environment sets NODE_ENV to production, NEXT_TELEMETRY_DISABLED to 1 and PORT to 3000, exposes 3000 and starts with yarn static-serve, so the container serves the built static output rather than running the Next.js server. The release process is documented separately, with the automated release procedure in the web app docs, and the release history in the repository confirms the cadence, with web-v1.103.0 published on 2026-10-20, web-v1.102.0 on 2026-10-06 and web-v1.101.0 on 2026-09-22. Only the web app carries versioned tags, which fits the split between the two applications.

Editorial conclusion

Adopt this repository when you are contributing to the Safe{Wallet} web or mobile application, or when you need the shared store and utility packages that both clients are built on. Do not adopt it as a self-hosted wallet deployment, since the product is a hosted application at app.safe.global and this repository is the client codebase. Verify first that your Node and Yarn versions match what the project pins, that you read the per app README rather than only the root one, since the setup guides differ between web and mobile, and that the workspace you are changing has its own test and lint commands wired into Turbo.

Frequently asked questions

What is inside the Safe{Wallet} monorepo?

apps/web is the Next.js web application, apps/mobile is the Expo and React Native mobile application, packages/store is the shared Redux store used by both, packages/utils holds shared utilities and TypeScript types, and config/ holds shared configuration files. The workspaces are managed with Yarn Workspaces, with turbo running the tasks across them.

How do I install and run the Safe{Wallet} apps locally?

Install Node.js and Yarn 4.5.3 or later by running corepack enable, then run yarn at the repository root. For a specific app use the workspace commands, for example yarn workspace @safe-global/web dev and yarn workspace @safe-global/mobile start, with yarn workspace @safe-global/web test for the web tests and yarn workspace @safe-global/web storybook for Storybook.

What checks does a contribution to Safe{Wallet} need to pass?

The best practices require using Yarn Workspaces commands for dependency management, ensuring type-check, lint, prettier and tests pass before pushing, and following the semantic commit message guidelines. Husky runs pre-commit hooks for linting, formatting and type-checking, with Jest for unit tests and Cypress for web end-to-end tests.

How does the Safe{Wallet} Docker image serve the web app?

The image is based on node:24-alpine with corepack enabled and the yarn httpTimeout set to 300000, then yarn install --immutable and yarn after-install. It sets NODE_ENV to production, NEXT_TELEMETRY_DISABLED to 1 and PORT to 3000, exposes port 3000 and starts with yarn static-serve, serving the built static output.

Official sources

  1. License: GPL-3.0
  2. Project website
  3. README
  4. Releases
  5. safe-global/safe-wallet-monorepo on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/safe-global-safe-wallet-monorepo.svg)](https://hysenlabs.com/projects/safe-global-safe-wallet-monorepo)

Was this useful?