# MALSync: the site list is generated into the README, and the build needs Node 24

> A browser extension and userscript that syncs episode progress between anime and manga tracking services and the sites you read on, including self-hosted media servers. The interesting parts are in the tooling: a supported-site table generated from a file at the repository root, a build that demands a very recent Node, and a dependency list that includes a rule against injecting unsanitised values.

**MALSync/MALSync** — Integrates MyAnimeList/AniList/Kitsu/Simkl into various sites, with auto episode tracking.

- Repository: https://github.com/MALSync/MALSync
- Website: https://malsync.moe
- Stars: 2,993 · Forks: 371
- Language: TypeScript
- License: GPL-3.0
- Published: 2026-09-24 · Updated: 2026-09-24 · Language: en
- Canonical page: https://hysenlabs.com/projects/malsync-malsync

## The summary names four list services and the readme names six

The project summary attached to the repository names four tracking services: MyAnimeList, AniList, Kitsu and Simkl. The prose at the top of the readme names those four plus Shikimori and MangaBaka, and the same six appear in the package description. So the one-line summary that search results and link previews show is two services behind the actual scope, and a reader who stops there does not know the extension covers two more lists than advertised. The capitalisation is not consistent either, with the summary writing the second service with an internal capital while the prose lowercases the same word. Versioning lines up, though: the manifest declares 0.12.5 and the newest release is also 0.12.5, published at the start of September, while the last commit is dated today.

## The supported-site table is generated into the readme from a root file

The largest block in the file is an HTML table with three columns, for anime sites, manga sites and media servers, and it sits between comment markers rather than being written by hand. The repository root holds a markdown file that is evidently its source. That arrangement has two consequences. Adding a site means editing a data file rather than a table, which is the right way round for a list this long. And the generated rows are visibly mechanical: each media server entry carries an empty link immediately followed by a labelled one pointing at the same address, and while the anime and manga columns use encrypted addresses throughout, the media server column uses the plain unencrypted form for the two self-hosted servers it links directly. The media server rows also each carry a wiki link anchored to that specific server, which is where the setup detail lives rather than in the readme.

## The build demands Node 24 while the type definitions stop at 16

The manifest states its engine requirements as a pair of floors:

```json
  "engines": {
    "npm": ">=11.0.0",
    "node": ">=24.0.0"
  }
```

A Node 24 floor is recent enough that it excludes most long-term-support releases, and requiring a matching npm major alongside it narrows the window further. For a project that solicits community pull requests, that is a real barrier to contributing, since a contributor has to be on the newest runtime before they can build. The type definitions tell a different story: the Node type package is pinned in the major-sixteen line, eight versions behind what the manifest demands. Nothing stops that combination from working, since the types only need to cover the APIs the code uses, but it means the compiler is checking calls against an interface eight major versions older than the runtime that will execute them.

## There are no runtime dependencies because everything ships bundled

The dependency list is entirely development dependencies, with no runtime section at all, and that is the correct shape for a browser extension: the build bundles what it needs into the shipped artifact rather than resolving packages at install time on the user's machine. The weight of that list is the build system. A webpack configuration directory sits at the root, with separate loaders for stylesheets, the preprocessor dialect used by the project, and the post-processing step, plus a loader that exposes something to the global scope and an archiver for packaging. Tests run on a single runner with an assertion library, and a directory-walking package is present, which is how the site list gets turned into generated output. The style tooling is the preprocessor plus its loader rather than plain stylesheets.

## A lint rule against unsanitised injection is an explicit dependency

One entry in the list deserves attention on its own: a plugin that exists to fail the build when unsanitised values are inserted into a page. This is an unusual thing to depend on deliberately, and it makes sense for this project specifically, since its entire job is running inside other people's sites and pushing its own interface into them. The same reasoning shows up next door in a serialization library whose purpose is to produce JavaScript source without creating an injection vector. So the project treats its injection surface as a security boundary and encodes that in the linter rather than in review guidance. Two other entries fit the same pattern of tooling used to test against real sites: a browser automation package and a third-party ad-blocking engine built for it.

## Publishing to the extension store is automated from the repository

The toolchain includes a package whose purpose is uploading a packaged extension to the Chrome Web Store, which means a release is pushed by a machine rather than by a person uploading a zip from a browser. Combined with the dependency-update configuration file at the root, the project automates both halves of maintenance: the store submission and the version bumps of its own dependencies. The store upload package sits in the development dependencies alongside the browser automation and the ad-blocking engine, all three of which exist to interact with the live web rather than with the project's own code. That is a coherent shape for a tool whose test suite necessarily reaches out to real sites, and it also means the same dependencies run in continuous integration, where the versions those automated updates choose land without a human reading them.

## Four separate tools police style, and the editor setup is committed

Quality tooling is spread across several files at the root: a flat configuration for the linter, a formatter configuration, a separate configuration for the stylesheet linter, a spelling dictionary with its own dictionary file, and an editor configuration. Three of those overlap in practice, since a formatter and two linters can each have an opinion about the same line, and the project resolves that by wiring the formatter into the linter rather than by dropping one. The repository also commits an editor directory, an npm configuration file, two type declaration shims for globals and for the component framework, and separate compiler configurations for the application and for tooling. All of it is visible to anyone who clones, which makes the contribution setup unusually explicit for a project of this size.

## Conclusion

MALSync suits someone who keeps a list on one of the supported tracking services and wants their progress to follow them across sites and onto a self-hosted media server, and the media server integrations are the part that distinguishes it from a simple progress marker. Two things to check before contributing. The build declares Node 24 and npm 11 as a hard floor, which is a narrow window for anyone whose tooling is not current. And the dependency list includes an explicit rule against inserting unsanitised values into pages, which tells you the project takes its own injection surface seriously even though its whole job is running code on sites it does not control.

## FAQ

### what is mal sync

An open-source browser extension and userscript that enables automatic episode tracking between list services including MyAnimeList, Anilist, Kitsu, Simkl, Shikimori and MangaBaka, and multiple anime and manga streaming sites, letting one list act as a bookmark across all supported pages. It is licensed GPL-3.0.

### Which websites support MAL-Sync?

A long generated table covering anime sites, manga sites and self-hosted media servers. The media server column covers Emby, Plex, Jellyfin, Komga, Suwayomi and Kavita, each linking to a wiki page for that specific server's setup.

### Is MAL sync safe?

The repository makes no safety claim. What it does state is the licence, GPL-3.0, and that problems are tracked through public GitHub issues with a Discord server linked for discussion.

### Why isn't MALSync working?

The readme does not document troubleshooting. It routes both questions and bug reports to the GitHub issue tracker, with a Discord invite linked from the top of the file.

### What does building MAL-Sync require?

The manifest requires npm 11 or newer and Node 24 or newer. There are no runtime dependencies listed, since the extension ships bundled, so the whole dependency list is build and test tooling including a browser automation package and a webpack configuration directory.

### How is the list of supported sites in MALSync maintained?

The table in the readme sits between comment markers and is generated, with a markdown file at the repository root as its apparent source. Adding a site means editing that data file rather than the table.

## Sources

- [License: GPL-3.0](https://github.com/MALSync/MALSync/blob/master/LICENSE)
- [MALSync/MALSync on GitHub](https://github.com/MALSync/MALSync)
- [Project website](https://malsync.moe)
- [README](https://github.com/MALSync/MALSync/blob/master/README.md)
- [Releases](https://github.com/MALSync/MALSync/releases)

---

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