# PreMiD Activities: the Discord presence catalogue and its pmd CLI

> PreMiD/Activities holds the source of every Activity published in the PreMiD Store, the small scripts that make a Discord user's presence show what site they are on. The repository is as much tooling as content, with a pmd command line that scaffolds a new Activity, runs a validating dev server and pushes live changes into the browser extension, plus shared schemas and lint rules that keep hundreds of community submissions consistent.

**PreMiD/Activities** — 🛒 Storage for Activities located at our Activity Library.

- Repository: https://github.com/PreMiD/Activities
- Website: https://premid.app/library
- Stars: 791 · Forks: 1,789
- Language: TypeScript
- License: MPL-2.0
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/premid-activities

## What an Activity actually is

An Activity is a small program that changes your Discord presence to reflect what you are doing on a website. The repository description calls the project storage for Activities located at the PreMiD Activity Library, and the README puts it more precisely: it contains the source code of all Activities available in PreMiD's Store.

That framing matters, because the repository is a catalogue with an unusually large number of contributors. Each Activity targets one site, and each one is a small TypeScript program that watches the page you are on and reports back what it finds. The store is the distribution channel, and the browser extension is the runtime that executes an Activity and pushes the result into your Discord status.

So the architecture has three parts. The extension is the client, installed in the browser and responsible for running the Activity code on the matching site. The repository is the source of truth for the Activities themselves. The store, at premid.app/store, is where end users install them, and the README links both the store and the library at premid.app/library.

For a developer, this means writing an Activity is a different exercise from writing a bot. There is no token, no gateway connection and no event loop on your side. The Activity reads the page, formats a string, and the extension handles the Discord side. The complexity you take on is the scraper, and the obligation to keep it working when the target site changes.

The implementation language is TypeScript, the licence is MPL-2.0, the default branch is main, and the last push was on 2026-10-19. There are no GitHub releases, which fits a repository whose versions are per-Activity rather than per-repository.

## The pmd CLI does the scaffolding and the validation

The repository ships its own command line tool, pmd, and it is the main reason this project is more than a folder of scripts.

Scaffolding is one command. Running npx pmd new my-activity-name starts a setup process that asks for basic information and generates the Activity structure with all the necessary files, so a contributor is not choosing directory names and file names by hand and getting them subtly wrong.

Development is the other one. Running npx pmd dev my-activity-name starts a development server, watches for changes in the Activity files, rebuilds automatically when you make changes, and validates the Activity against PreMiD standards. The --validate option adds further checks for metadata and images, which is the check you want before opening a pull request rather than after a reviewer asks for it.

The CLI is a local package in the repository rather than something fetched from a registry. The package.json lists pmd as file:cli and premid as file:premid, so the workspace links the CLI and the shared runtime library from source. The prepare script reflects that arrangement: it installs and builds the cli directory first, then reinstalls the root dependencies with scripts disabled.

The npm scripts are minimal and deliberate. There is lint and lint:fix, both running eslint with a cache, and dev, which is simply pmd dev. Everything else a contributor needs is expected to go through the CLI rather than through ad hoc npm commands.

## The live reload loop depends on the extension's developer mode

Testing an Activity involves the browser extension, and the README is explicit about the sequence because it is not obvious.

You install the PreMiD Extension in your browser. Then you open the extension icon, go to settings, and enable Activity Developer Mode. Then you run npx pmd dev my-activity-name. While developer mode is on, the pmd tool automatically sends your Activity to the extension, so you open the site the Activity supports and see it working, and any change you make is picked up and sent over again without you reloading anything by hand.

The README calls this out as a development workflow that avoids manually loading the Activity each time you change it, which is the normal pain of extension development where the content script has to be re-injected.

The extension being mandatory is also the shape of the whole project. There is no headless path here. An Activity is not a service, it is a page script that the extension runs in a browser, and the developer mode switch is the seam between your local work and the extension instance you are testing in.

That seam is why the tool has to validate as it goes. The pmd dev command validates the Activity against PreMiD standards on every rebuild, so a mistake in the metadata or a missing image surfaces during development rather than during a maintainer review.

## The monorepo layout and the shared packages

The top level listing shows a workspace rather than a single package, and each directory has a job.

The websites directory is where the Activities themselves live, one per site. The premid directory is the shared runtime library that every Activity builds against, linked into the workspace as file:premid. The cli directory holds the pmd tool, linked as file:cli. The schemas directory holds the JSON schemas that describe an Activity's structure, and there is a matching lint plugin, eslint-plugin-json-schema-validator, plus custom rules in the eslint-rules directory, so a malformed Activity fails the lint step rather than the store.

The @types directory holds type definitions, and tsconfig.base.json carries the shared TypeScript configuration, with @total-typescript/tsconfig providing the strict preset underneath it.

Two files reveal how the project is run day to day. crowdin.yml points at Crowdin, which is how user-facing strings in Activities get translated. dmca.json is a takedown registry for copyright complaints, which is a sensible thing to have in a repository where hundreds of people write scrapers for other people's websites.

The tooling choices are current. TypeScript 6.0.3, ESLint 10.8.1 with the @antfu/eslint-config, Vitest 4.1.11 with the coverage and UI packages, and eslint-plugin-format for formatting inside the lint step. The engines field requires Node.js 20 or newer, and the README's setup instructions ask for Node.js version 20 or higher.

## Getting an Activity from an empty folder to a pull request

The whole path is documented in the README, and it is short enough to follow end to end.

Install Node.js 20 or higher, then clone and install the dependencies:

```bash
git clone https://github.com/PreMiD/Activities.git
cd Activities
npm install
```

Before writing code, the README asks you to read the documentation at docs.premid.app to understand how Activities work, and to browse the existing Activities for examples and best practices. That second step is the practical one. With hundreds of Activities in the tree, the conventions for detecting a page, handling a site that is not logged in, and formatting a presence are easier to copy than to invent.

Then create the Activity:

```bash
npx pmd new my-activity-name
```

Develop it with live reload:

```bash
npx pmd dev my-activity-name
```

And the package metadata that ties the workspace together:

```json
  "name": "activities",
  "type": "module",
  "private": true,
  "license": "MPL-2.0",
  "engines": {
    "node": ">=20.0.0"
  },
```

When the Activity is ready, the README's list is short: make sure it passes all validation checks, create a pull request to the repository, and wait for a review from the maintainers. There is no separate submission portal and no automated publish step, which means the store's contents move at the pace of human review.

## Where the model breaks down

The design has clear limits, and they are worth naming before you spend a weekend on a scraper.

The first is that an Activity lives or dies with the site it targets. Discord's own status updates break when a site changes its markup, and an Activity that reads a page's DOM is more fragile still, because any class name or selector can change without notice. The repository exists as a shared catalogue precisely because these are small and numerous, but it does not remove the maintenance obligation, and it means the reviewer is looking at code that will rot.

The second is that the Activity only runs in a browser with the extension. There is no server-side deployment, no headless execution and no fallback if the extension is missing. For a community catalogue that is the right trade, since the extension already handles the Discord protocol, but it also means the reach of an Activity is bounded by the extension's user base.

The third is review throughput. A pull request needs maintainer review, and a project with this many contributors and this many small submissions has a queue. The README also asks contributors to make sure validation passes before submitting, so the reviewer's job is to judge quality rather than to fix obvious breakage.

The fourth is the licensing shape for contributors. MPL-2.0 is a file-level copyleft licence, which means an Activity you contribute is published under MPL terms while the rest of your work stays as you like it. Contributors are not asked to assign copyright, which is friendlier than many corporate projects, but it does mean the store's contents carry a specific licence and anyone reusing an Activity needs to respect it.

## Commit conventions, translations and who reviews

The repository enforces its commit format. The README says it strictly enforces the use of commitlint and points to the Commit Convention guide in .github/COMMIT_CONVENTION.md, with the configuration in commitlint.config.js at the root. The conventional commits format is not a style preference here, it is a gate.

The scripts behind it are equally visible. lint runs eslint over the tree with a cache, and lint:fix applies the fixes. The lint configuration is eslint.config.mjs with the flat config style, built on @antfu/eslint-config and extended with eslint-plugin-format for formatting and eslint-plugin-json-schema-validator for checking Activity metadata against the schemas. Tests run under Vitest, with the coverage package wired in.

Translation is handled through Crowdin rather than by editing every Activity in every language. That matters for contributors, because a new Activity contributes English strings and the rest follows through the translation platform rather than through a pile of language folders.

The copyright side is handled by dmca.json, a machine-readable list of takedown requests, which tells you the project expects to receive complaints about Activities that scrape content someone owns, and has a process for removing them.

On maintenance, the repository is not archived and the last push was on 2026-10-19, so contributions continue to land. The topics list includes hacktoberfest, which suggests the project recruits outside contributors deliberately, and the presence of CODE_OF_CONDUCT-style governance in .github, a Discord community link, and a store with a live catalogue all point to a self-sustaining community rather than a hobby project with a fading maintainer.

The practical summary for an engineer: this is a well-tooled catalogue with strict conventions and a human gate, where the tool does the tedious work of scaffolding and validation and leaves the interesting work, the scraper, to you.

## Conclusion

Adopt PreMiD Activities if you want to contribute a Discord presence for a site the store does not cover yet, and you are comfortable writing a scraper that will need maintenance when that site changes. Do not adopt it as a general Discord bot framework, since an Activity is a presence display rather than a bot, and it needs the PreMiD browser extension installed to do anything at all. Before you open a pull request, run npx pmd dev with the extension in Activity Developer Mode, run the validation checks, and read the commit convention guide, because the repository enforces commitlint and a review by maintainers is part of the process.

## FAQ

### What is a PreMiD Activity?

An Activity is a small program that enhances your Discord presence by showing what you are doing on a particular website. The Activities are written in TypeScript, stored in this repository, distributed through the PreMiD Store and executed by the PreMiD browser extension.

### How do I create a new Activity with the pmd CLI?

Run npx pmd new my-activity-name, which starts a setup process asking for basic information and generates the Activity structure with the necessary files. You then develop it with npx pmd dev my-activity-name, and add --validate for extra checks on metadata and images.

### How do I test an Activity before submitting it?

Install the PreMiD Extension in your browser, enable Activity Developer Mode in its settings, then run npx pmd dev my-activity-name. The tool sends the Activity to the extension automatically and pushes changes as you edit, so you can see it on the target site without reloading manually.

### What does submitting an Activity involve?

Make sure the Activity passes all validation checks, create a pull request to the repository, and wait for a review from the maintainers. The repository strictly enforces commitlint, so the commit messages must follow the convention guide in .github/COMMIT_CONVENTION.md.

### What licence and tooling does the PreMiD Activities repository use?

The package is licensed MPL-2.0 and is marked private, requiring Node.js 20 or newer. Tooling includes TypeScript 6, ESLint 10 with a JSON schema validation plugin for Activity metadata, Vitest 4 for tests, and pmd and premid as local workspace packages.

## Sources

- [Issues](https://github.com/PreMiD/Activities/issues)
- [License: MPL-2.0](https://github.com/PreMiD/Activities/blob/main/LICENSE)
- [PreMiD/Activities on GitHub](https://github.com/PreMiD/Activities)
- [Project website](https://premid.app/library)
- [README](https://github.com/PreMiD/Activities/blob/main/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/premid-activities
