Library / SDK
OpenUserJS/OpenUserJS.org avatar
OpenUserJS/OpenUserJS.org

OpenUserJS.org: a self-hosted repository and discussion site for FOSS user scripts

The home of FOSS user scripts.

1,012 stars373 forksJavaScriptGPL-3.0

At a glance

What is it?
OpenUserJS.org is a Node.js web application that lets people publish, install and discuss user scripts, and it is structured as an ordinary Express and MongoDB MVC application with an Ace editor in the browser. The oddity in its history is the version numbering, since the last GitHub release tag is from 2015 while the package version is 0.6.0 and the last push was in September 2026.
Who is it for?
OpenUserJS.org fits a community that wants to run its own user script repository, with accounts, a script editor, and discussion, rather than relying on a hosted service. It is the wrong choice for a single user who only wants to install scripts, and it is the wrong choice if you need a modern stack, because the package depends on Express 4, Mongoose 5 and Bootstrap 3.
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 last received commits 34 days ago.
What is it written in?
Mainly JavaScript, 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

What a user script repository actually has to do

OpenUserJS.org is the home of Free and Open Source Software user scripts, built using Node.js and other web familiar technologies, and it is a full web application rather than a library.

The problem space is narrow but not trivial. A user script is a piece of JavaScript, with metadata in a comment block, that a userscript manager injects into a page. A repository for them needs to do several ordinary things that are easy to underestimate. It has to store the script source and its metadata, let someone edit it in the browser with syntax highlighting, let someone install it, let other people comment on it and rate it, let an author release new versions, and let anyone fork and improve a script.

Every one of those is visible in the dependency list. Ace is the in-browser code editor, ace-builds being the prebuilt distribution. highlight.js is a second highlighter, which suggests the site highlights code in the display pages as well as in the editor. js-beautify formats scripts. marked and marked-highlight render Markdown, and bootstrap-markdown is the Bootstrap styling for it. A pegjs parser generates code from a grammar, which is how a metadata block such as the name and the match patterns and the version gets parsed out of a script's comment header. diff computes differences, which is what shows a new version against the old one.

The rest is web application machinery. express is the framework, with body-parser, compression, express-minify, less-middleware for stylesheets, method-override, and morgan for request logging. express-session with connect-mongo holds sessions in MongoDB. express-rate-limit throttles requests, and there are two captcha integrations, express-hcaptcha and express-svg-captcha, with the hCaptcha one being a fork maintained under the same organisation.

The data layer is MongoDB through mongoose, and passport handles authentication, with strategies for GitHub, GitLab, Google, Imgur, Reddit, Steam and a kerberos module for what looks like a local directory service. That list of strategies is the interesting part, because it is the list of ways the community around the project wanted to log in, and each strategy was added because a contributor needed it.

The topics confirm the shape: express, expressjs, mvc, node, nodejs, online-expected, userscript-management and webapp. The online-expected tag is the one that says something, since it marks the project as a hosted service that expects a public presence rather than a library you embed.

The MVC layout, and the Express surface it exposes

The top level listing is a textbook Express application layout, and reading it tells you how the routing is organised.

There is app.js, which is the application entry point, and it is the main field in package.json, so the process starts there. There is routes.js and routesStatic.js, two route files, which is the standard split between the dynamic routes with their controllers and the static asset serving. Then controllers/, models/ and views/ for the MVC layers, libs/ for the shared library code, public/ for static assets, and dev/ for development tooling.

That structure is worth noting because it is the conventional one, and the project explicitly tags itself mvc. There is no framework magic here, no build step for the server, and the application is a Node process that serves views. That has a consequence for anyone evaluating it today, which is that it is a 2015 era stack that has been kept running rather than a modern rewrite.

The package version is 0.6.0, and the dependency versions tell the story of how it has been maintained. Express is 4.21.2, which is the current 4.x line. Mongoose is 5.13.23, a 5.x release. Bootstrap is 3.4.1, the last 3.x release. Moment is 2.30.1 for dates, with moment-duration-format alongside. And the passport strategy packages are old in the same way, passport 0.4.1 with passport-google-oauth20 at 2.0.0.

The pattern is consistent: the Express line and the security-adjacent packages have been kept current, while the ORM and the CSS framework have not. Mongoose 5 and Bootstrap 3 are the two that stand out, and both are the kind of dependency where staying on an old major version is a decision with consequences rather than an oversight, because the newer major versions of both carry breaking changes.

Three dependencies are git references rather than published versions, and each one is a fork maintained by the same organisation. bootstrap-markdown is a git URL pinned to a marked4.x branch, express-hcaptcha is pinned to a forkUpdate branch, and github is a git URL pinned to a specific commit of octokit's rest.js. Those three are the ones to look at first if you deploy this, because a commit-pinned dependency is not covered by semver and does not receive the updates you would expect.

Also present are aws-sdk at 2.1693.0 and the octokit auth-oauth-app, which between them suggest the application talks to GitHub and to AWS, most likely to import scripts from a repository and to store or serve assets.

Two version numbers, and what a fork in the dependency list actually means

The version history of this project is where the most confusion lies, so it is worth laying out plainly.

The three GitHub release tags are v0.2.0 on 2015-08-25, v0.2.1 on 2015-10-21 and v0.2.2 on 2015-11-17. The package version in package.json is 0.6.0. The last push was on 2026-09-19 and the repository is not archived.

So the published releases stopped in November 2015 at version 0.2.2, while the working version in the tree is 0.6.0 and development has continued right up to September 2026. That gap is more than a decade, and it has a concrete consequence: there is no tagged release that matches the current code. If you want to run this in production, you are tracking a branch, and the version string in package.json is the only marker of what you are running.

The second thing the version story tells you is that the maintainers chose to keep the project alive by updating dependencies rather than by re-architecting. Express 4.21.2 is a maintained line. The security-relevant packages, the captcha integrations, the rate limiter, the session handling, are all at current versions within their major lines. The parts that have not moved, Mongoose and Bootstrap, are the parts where a rewrite would have been visible.

Now the fork dependencies, because that is the part with real operational weight. Three of them are git URLs rather than registry versions: bootstrap-markdown pinned to a marked4.x branch, express-hcaptcha pinned to a forkUpdate branch, and github pinned to commit 29dedb3 of the octokit rest.js repository. The github entry in particular is a git URL pinned to a specific commit of octokit's rest.js repository.

That is a reasonable engineering decision and a real operational one. A commit-pinned fork does not receive the upstream security fixes that a registry version would, so it is a dependency you own rather than one you consume. For a public community site, where anyone can create an account, that is the part of the dependency list to audit most carefully.

The other thing the old stack implies is that the front end is Bootstrap 3 with jQuery at 3.7.1 and Font Awesome 4.7.0. A community site running that combination is running a UI stack whose major versions have been superseded, and while a server-rendered Bootstrap 3 site is not a security risk in itself, it is a maintenance one, since a new contributor will be reaching for current tooling and finding a decade old one in the repository.

What a user script is, and why the metadata parser exists

It helps to be precise about the artefact being managed, because every dependency in this repository exists because of something about how user scripts work.

A user script is JavaScript that a userscript manager injects into a page before the page's own scripts run. It carries a metadata block in a comment, and that block is not decoration. It names the script, gives its version, states the URLs it matches, and declares the grants it wants, so the manager knows which permissions to ask the user for and which pages to run it on.

That metadata is why pegjs is in the dependency list. A metadata block has a grammar, and a parser generator is how you get a correct parser for it rather than a regular expression that breaks on the first script with an unusual value. The same reasoning applies to the version comparison logic, where diff and a comparison library decide whether a user has an out of date script, and to js-beautify, which reformats the source so that a diff between two versions shows the actual change rather than a reindentation.

The other end of the loop is the user agent side. A script is only useful if a userscript manager can install it, which means the repository has to serve something a manager understands rather than a web page. That is the part the framework handles, and it is why the site is a full application rather than a page of downloads, because installing a script means resolving a URL, checking the version, and writing the metadata into the manager.

Ace exists for the same reason the highlight.js dependency does. The editor is where an author writes the script and edits the metadata block, and it needs to understand that the block is structured rather than free text, so it can offer completion and validation for the fields. highlight.js then does the same job on the read side, where a visitor is looking at a script in a page.

The two captcha packages, express-hcaptcha and express-svg-captcha, sit at the other end of all this. The site has user accounts, and a public registration form on a community site is a spam target, so there is a captcha on the registration path, and the project maintains its own fork of the hCaptcha integration and ships a self-generated SVG captcha as well, presumably so that a deployment is not dependent on hCaptcha being reachable.

So the dependency list reads as a specification of the whole workflow once you know what a user script is: parse the metadata, edit it with structure awareness, publish it, serve it in a form a manager can install, track versions, and keep the registration door shut.

The alternative to a shared repository, and what running your own costs

The honest comparison here is not with another repository software package, it is with the two other ways of getting user scripts to the people who want them.

The first alternative is the hosted service. Almost every user script today comes from a central site with a large catalogue, a rating system, a comment thread and a well known update mechanism, and a browser extension that knows how to talk to it. For a single user, that is better than anything you can run yourself, because the catalogue is the value and the catalogue is a network effect. A self-hosted repository with fifty scripts has no catalogue, no ratings, and no comments from strangers, so a user installing from it gets less than a user installing from a big site, no matter how well the software works.

The second alternative is no repository at all. If you or your team write the scripts, you can host them on a static file server or in a git repository, point your userscript manager at them, and skip all of this. That has a real advantage: no accounts, no sessions, no captcha, no database, no moderation surface, and no third party in the path of your code updates. It also means no discovery, no version history in the browser's eyes, and no place for people to report that a script broke.

So the case for running OpenUserJS.org yourself is a case about the community rather than the software. It fits an organisation that wants its scripts under its own control, a user group that wants a shared catalogue in its own hands, or a group that wants the discussion and review around a script to happen in the open rather than in a general purpose site. The case against is that you take on the operational work of running a public web application with user accounts, and the dependency list tells you how much of that is old.

The operational work is worth spelling out, because it is not just the server. There are accounts, so there is registration, so there is captcha, and the presence of both an hCaptcha integration and a self-generated SVG captcha suggests the site is trying to avoid depending on a third party for that. There are sessions in MongoDB, so the database is not optional. There are rate limits, so there is abuse to manage. There is a MongoDB driver and an ORM layered over it, so there is a schema to maintain. And there are three git-pinned dependencies that will not update themselves.

If you deploy this, the realistic path is to run it as is rather than to upgrade it, which means you own a decade-old stack and should be treating its dependencies as part of your own codebase. That is a legitimate choice for a community project, and an expensive one for anyone who expected a current Node application.

Editorial conclusion

OpenUserJS.org fits a community that wants to run its own user script repository, with accounts, a script editor, and discussion, rather than relying on a hosted service. It is the wrong choice for a single user who only wants to install scripts, and it is the wrong choice if you need a modern stack, because the package depends on Express 4, Mongoose 5 and Bootstrap 3. Before adopting, read the STYLEGUIDE.md and CONTRIBUTING.md files, check the MongoDB requirement and the connect-mongo session store, and plan for the fact that the release tags stopped in 2015 even though development continued, so you will be tracking a branch rather than pinning a published version.

Frequently asked questions

What is OpenUserJS.org and what is it built with?

It is a self-hosted web application for publishing, installing and discussing Free and Open Source Software user scripts. It is a Node.js and Express application with MongoDB through Mongoose, an Ace editor in the browser, Passport authentication with GitHub, GitLab, Google, Imgur, Reddit, Steam and Kerberos strategies, and sessions in MongoDB through connect-mongo.

How is the OpenUserJS.org codebase organised?

In the conventional Express MVC layout. app.js is the entry point and the package main, routes.js and routesStatic.js hold the dynamic and static routes, and there are controllers/, models/ and views/ directories, plus libs/ for shared code, public/ for static assets and dev/ for development tooling.

Are the OpenUserJS.org dependencies up to date?

Mixed, and the pattern is consistent. Express is on the current 4.x line and the security-adjacent packages are current within their major versions, but Mongoose is 5.13.23, Bootstrap is 3.4.1 and jQuery is 3.7.1. Three dependencies are git references rather than registry versions, including a commit-pinned octokit rest.js fork, which means they are dependencies you own rather than ones that update themselves.

What is the current version of OpenUserJS.org?

The package version in package.json is 0.6.0, but the last GitHub release tags are v0.2.0, v0.2.1 and v0.2.2 from August, October and November 2015. The repository is not archived and the last push was on 2026-09-19, so development continued long after the releases stopped and there is no tagged release matching the current code.

Official sources

  1. License: GPL-3.0
  2. OpenUserJS/OpenUserJS.org on GitHub
  3. Project website
  4. README
  5. Releases
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/openuserjs-openuserjs-org.svg)](https://hysenlabs.com/projects/openuserjs-openuserjs-org)

Was this useful?