The Unlock monorepo holds the contracts and the web app together
Ʉnlock is a protocol for memberships built on a blockchain.
At a glance
- What is it?
- This repository holds all the code deployed by the membership protocol, from the Solidity smart contracts to the web app running at `unlock-protocol.com`, organised as a yarn workspace monorepo. It suits a developer who wants to read or run a blockchain membership protocol end to end, and it is a deployment rather than a library.
- Who is it for?
- This monorepo suits a developer who wants to read a blockchain membership protocol end to end, or run the contracts and the dashboard locally to see how a lock becomes a subscription, and who is prepared to work inside a large yarn workspace. It is the wrong thing to adopt as a dependency, since the repository is the deployment itself rather than a package, and it is the wrong thing for a team that needs a hosted key management service rather than a protocol implementation.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- GitHub does not report a main language for this repository.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The repository is the deployment, not a library
The project documentation states the scope in one sentence. This repository includes all the code deployed by the project, including smart contracts and the web app running at `unlock-protocol.com`.
That sentence rules out the most common reason to look at a repository like this. There is nothing to install into your project and no API to call, because the repository is the running system. The top-level entries make that concrete: a smart-contracts directory, an `unlock-app` directory, a locksmith directory, a wedlocks directory, a subgraph directory, a graph-service directory, a governance directory with its own governance-app, a paywall-app, a provider, a docker directory, and `unlock-protocol-com`, which is the marketing and documentation site.
What the project is, in its own framing, is a membership protocol built on a blockchain, which enables creators to monetize their content or software without relying on a middleman. It lets consumers manage all of their subscriptions in a consistent way, and it lets them earn discounts when they share the best content and applications they use.
The last clause is the part with an unusual design. The sharing incentive is what turns a subscription list into a distribution network, and it is the reason the protocol needs a notion of a lock that can be a membership, a key or a discount, and why there is a separate airdrops directory in the tree.
For a reader, the repository is best approached as a codebase to study. The essay on why the project is being built is linked from the getting started documentation for the argument, and the code is here for the implementation.
Getting the code and building the workspaces
The getting started section is concrete, and it starts with a clone:
# get the code
git clone https://github.com/unlock-protocol/unlock
cd unlockYou will need yarn installed globally, and then the install step, which the documentation warns may take a while:
yarn
# install all dependencies (...may take a while)After that comes the build of all packages:
yarn buildAnd then the pattern for running anything inside the repository, which is worth internalising because it is the only way most of the scripts are reached. The project says that to execute commands inside the repo, they use the pattern yarn workspace <workspace name> <command>, and gives two examples:
# build the contracts only
yarn workspace @unlock-protocol/smart-contracts build
# validate lint for paywall
yarn workspace @unlock-protocol/paywall lintThe workspace list in the package manifest shows how large the tree is. The workspaces array covers the packages directory, the governance and governance-app directories, smart-contracts, subgraph, tests, the main app, the client library, the marketing site, locksmith, paywall, paywall-app, wedlocks, provider, docs, graph-service and airdrops. The root package is private, named `unlock`, with the description a protocol for decentralized access control.
One detail in the manifest tells you how a large JavaScript monorepo keeps its tooling aligned. The root test script is a placeholder that echoes an error and exits 1, which is the npm default for a package with no tests, while the real testing lives elsewhere, with vitest and its coverage plugin in the development dependencies alongside eslint, prettier and husky. The scripts block also includes a packages script that runs a yarn workspaces foreach over a curated list of workspace names, which is how one command targets the subset of packages that matter rather than all of them.
Running a local chain and provisioning dummy locks
The protocol can be run locally with Docker, and the command is one line:
cd docker && docker compose up --buildWhat that creates is described explicitly. It brings up the required infrastructure, namely a database, a local Ethereum test network and the subgraph, and it starts core services such as the Locksmith API and a Wedlocks mailing service for debug purposes. The mailing service existing in a local environment is a good sign of how much of the system the local stack actually exercises.
There is a configuration subtlety worth noting, because it is the kind of thing that produces a container that starts with the wrong settings. The project states that config is defined in both docker-compose.yml and docker-compose.override.yml, which is the standard Docker Compose pattern for local overrides, and it is where you would point the stack at a different chain or different service URLs.
Deploying the contracts and creating test data comes next. The following script will deploy the contracts, create some dummy locks and send you some local tokens for development:
cd docker
docker compose exec eth-node yarn provisionThe order matters and the documentation makes it explicit. The protocol has to be running before you can provision against it, and the chain has to exist before the contracts can be deployed to it. The dummy locks and the local tokens are what a developer then uses to exercise the dashboard.
There is also a protocol health check that anyone can run from the command line, with the caveat that the dependencies have to be installed and the packages built first:
yarn workspace @unlock-protocol/networks check:verifyFor a project whose subject is a protocol, a self-service verification command of that name is the feature that most reduces the cost of contributing, because it answers the question of whether the local chain is in a coherent state before you start debugging anything else.
The dashboard, the paywall and the two local ports
The dashboard is described as living in the `unlock-app` folder of the repository, and the launch commands are short:
# install deps
yarn
# start Unlock main app
yarn workspace @unlock-protocol/unlock-app startTwo ports come up, and the documentation gives them. The first is http://localhost:3000, described as where you start using the application and deploy locks locally, and the second is http://localhost:3002, the static landing page site.
That split is a small but revealing detail. The landing page is static and served separately from the application, which means the marketing surface and the dashboard are separate deployables in the same repository. It is also the same pattern the docker stack follows, where Locksmith is the API service and the apps are separate from it.
The paywall appears twice in the tree, as a paywall-app directory and as a workspace named paywall, and the lint example in the build section targets the paywall workspace. A paywall is the piece that turns a lock into an access decision on a content site, and it is the part a third-party developer is most likely to want to read and copy, since the protocol itself is the least of the work in shipping a paid article.
The repository also has a provider directory, an airdrops directory and a graph-service directory, so the surface area includes the server that lets wallets sign messages on a site's behalf, the mechanism for distributing tokens, and a service that answers graph queries about the state of locks.
Secrets come from 1Password, and the reference syntax is worth learning
The Secrets section describes an arrangement that will be familiar to anyone who has contributed to a project with real infrastructure behind it. Secrets are stored in the project's 1Password account in the API and Services Vault, and they can be loaded in the GitHub Actions through the use of dedicated actions.
The example given is a workflow step:
steps:
- name: Load secrets from 1Password
uses: 1Password/[email protected]
with:
export-env: true
env:
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}
USERNAME: op://secrets/test-api/username
CREDENTIAL: op://secrets/test-api/credential
... more steps that require USERNAME and CREDENTIAL to be setThe reference URIs have a documented syntax, op://<vault>/<item>[/<section>]/<field>, and the documentation walks through one example. The reference URI op://app-cicd/aws/secret-access-key would be interpreted as vault app-cicd, item aws, field secret-access-key.
This is a good pattern to copy, and it is worth understanding why it matters for a protocol repository. A membership protocol's test suite needs real service credentials, because the subscription flow touches payment processors, email delivery and the key management service. Putting those credentials in a shared 1Password vault and referencing them by URI means the repository never holds a secret, the CI logs never print one, and access to a secret is a vault permission rather than a repository permission.
The Dockerfile shows the same pattern on the local side, with a stage that installs the 1Password command line client so the container can fetch what it needs at build time.
Where this is hard to adopt, and what it is actually for
Three things limit who should pick this up, and none of them is a defect.
The first is that the output is a deployment, not a component. There is no package to add to a project, because the repository is the web app, the API, the subgraph and the contracts all at once. A team that wants a membership system will end up deploying this rather than depending on it, and that is a hosting, key management and monitoring commitment, not a dependency.
The second is the toolchain. The build needs yarn installed globally, the dependency install is called out as slow, and the local protocol needs Docker and a local Ethereum test network with a subgraph. The Dockerfile reinforces the weight, since it installs git, rsync, python3, postgresql, a JDK and build-essential before it installs anything from the project, and it pins a specific Node base image, 22.21.0-bullseye, with a comment explaining that the graph CLI binary does not work with bookworm, which is the default for Node 20 images.
The third is the gap between the branch and the releases. The repository is not archived and the last push was on 2026-10-20, so work is current, but the published release tags are date-stamped, with 20250325-1 from March 25 2025 followed by 20250307-1 and 20250117-1. Those tags trail the branch by well over a year, which is typical of a project whose releases track deployable snapshots rather than library versions.
What the repository is for is thus narrower than the topic list suggests. It is for reading how a real membership protocol is put together, and for running one locally to see the whole path from a lock to a subscription. For a team that wants to issue access tokens on a chain, that is a fine thing to spend a weekend on, and the local Docker path with the provision script makes the weekend a short one.
Editorial conclusion
This monorepo suits a developer who wants to read a blockchain membership protocol end to end, or run the contracts and the dashboard locally to see how a lock becomes a subscription, and who is prepared to work inside a large yarn workspace. It is the wrong thing to adopt as a dependency, since the repository is the deployment itself rather than a package, and it is the wrong thing for a team that needs a hosted key management service rather than a protocol implementation. Before you build on it, read the workspace list in the package manifest to see which pieces are separable, run the local protocol with Docker Compose so you have a real chain to deploy against, and read the LICENSE file at the repository root, since the README badge states MIT.
Frequently asked questions
What does this repository contain?
It includes all the code deployed by the project, including the smart contracts and the web app running at unlock-protocol.com. The protocol is a membership system built on a blockchain, which lets creators monetize content or software without a middleman and lets consumers manage their subscriptions in one place.
How do I run the protocol locally?
Use Docker, with cd docker and docker compose up --build, which creates the database, a local Ethereum test network and the subgraph, and starts services such as the Locksmith API and the Wedlocks mailing service. You then deploy the contracts and create test data with cd docker and docker compose exec eth-node yarn provision.
How do I run one of the applications?
The main dashboard lives in the unlock-app folder. Run yarn and then yarn workspace @unlock-protocol/unlock-app start, which serves the application on http://localhost:3000 and the static landing page on http://localhost:3002.
How are secrets handled in this repository?
They are stored in the project's 1Password account in the API and Services Vault and loaded in GitHub Actions through dedicated actions. The reference URI syntax is op://<vault>/<item>[/<section>]/<field>, and the Dockerfile installs the 1Password command line client so containers can fetch what they need.
Official sources
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.
[](https://hysenlabs.com/projects/unlock-protocol-unlock)