Self-hosted service
zhblue/hustoj avatar
zhblue/hustoj

HUSTOJ: five templates in the heading, six in the list, one volume declared

Popular Simple Open Source Online Judge based on PHP/C++/MySQL/Linux for ACM/ICPC and NOIP training, with easy installation.

3,828 stars830 forksJavaScriptGPL-2.0

At a glance

What is it?
HUSTOJ is a long-running Chinese online judge for programming training, with a self-hosting-friendly stack and an unusually explicit licence section. Its page contains a heading that miscounts its own list, a container build with a switch pointing at a file it never copies, and a changelog that turns two free features into paid ones.
Who is it for?
HUSTOJ suits a school, training class or regional contest that needs a judge it can host and modify itself, and that reads Chinese documentation without difficulty. Four things to know before deploying it.
Can I use it commercially?
Yes, with conditions. GPL-2.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 2 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 November 14, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • zhblue/hustoj3,828 ★ · +28
Star history
Repository2026-09-242026-11-14
zhblue/hustoj3.8k3.8k

28 Stars in the last 51 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

The heading says five templates and the list has six

The demos section is titled, in Chinese, the five built-in templates. It then lists six. Two are attributed to the same individual contributor, one to another contributor, and three carry no attribution at all. Each is a link to a demo site, and every one of those links is plain http rather than https. To switch between them you edit a single template variable in a PHP include file under the web directory, at a default location given as a path under the judge user's home. So the mechanism is genuinely simple and the switch is one value, which is the part of this design that has aged well. The count in the heading is simply stale, left over from when there were five, which is a fair summary of how this page is maintained: the code moves weekly and the prose above it moves when someone is editing that paragraph.

The default theme is a fork of another project's default

One of the listed templates is labelled as the original version of a theme whose name abbreviates the third generation of a CSS framework. That is the default this system ships, so out of the box HUSTOJ presents itself using a fork of a well known open source web template, while the five alternatives around it were contributed by individuals. The credits section confirms the pattern by listing the source projects that came from: several other online judge systems by name, plus a long list of infrastructure and front-end libraries including the web server, the language runtime, both databases, a cache, and a set of editors and widgets. That list is worth reading on its own, because it tells you what this project is: a small amount of original judge logic sitting on top of a stack assembled from other people's projects, with the original parts being the parts the licence applies to.

The container's mirror switch points at a script the build never copies

The container file has two build arguments. One decides whether to append the maintainers' package mirror list, and its default is yes. The other decides whether to install certificate authorities, and its default is no. The mirror step runs a shell script from a path inside the image. The line that would copy that script into place, directly above it, is commented out. So with the default arguments the build asks for a script that is not there, the step fails, and a trailing clause that tolerates failure swallows the error. The result is a build that looks like it switched package mirrors and did not. The same pattern appears on the certificate line, which is skipped entirely at its default value and, when enabled, uses a different package command spelling from the rest of the file. Neither issue stops the image from working; both mean the two advertised build switches are unreliable.

Only one volume is declared and the ones that matter are commented out

There is a commented out volume declaration in the container file that names six paths: a generic volume, and five under the judge user's home covering backups, data, configuration and the web directory, plus the database's own directory. The line that is live declares only the generic one. A judge needs its database and its problem data to outlive the container, and both of those live in exactly the paths that were commented out. So a container replaced rather than restarted loses them unless something outside this file mounts them. The rest of the file is conventional: an Ubuntu 24.04 base, a web server, a database, the language runtime and its modules, the compilers and a parser generator that the in-container judging needs, and the source tree plus a setup script copied in. The entry point is a shell script invoked through a shell explicitly, and no unprivileged user is created, which is expected for a process that has to bind port 80. The two lines, as they appear in the file, are:

code
# VOLUME [ "/volume", "/home/judge/backup", "/home/judge/data", "/home/judge/etc", "/home/judge/web", "/var/lib/mysql" ]
VOLUME [ "/volume" ]

The licence section says hosted use is not distribution

The copyright section is the most substantial writing on the page and it goes well beyond stating a licence. The project is GPL version 2, applied to the original code only, with borrowed components keeping their own terms. It asks readers doing research or writing systems to credit the project, then immediately says that request is a suggestion and not a requirement, and it points at a 2012 journal paper as the thing to cite. The substantive part comes after: the only real requirement is that redistributors provide source when they distribute, where distribution is defined as installing a derived product on a customer's server, so customers must receive your modified source privately and the licence must be included and marked. It then says that offering the derived work as a hosted service on your own servers is not distribution, so you need not open source it, need not credit the front end, and may remove the original footer copyright notice without breaching the licence. It adds that calling the system's functions over a database or an HTTP interface does not bring your code under the licence at all. That is the project's own interpretation, published clearly, and it is worth reading as carefully as the licence itself.

The list asks you to keep a footer code and elsewhere permits deleting it

There is a short section of requests aimed at people who find the project useful, and it mixes three different kinds of ask. The first two are about the code: give the repository a star, and keep the QR code in the site footer. The rest are commercial or promotional: visit the project's problem bank and pay to download problems, recommend it to colleagues, scan a daily payment red packet at the bottom of the page, and put the project's address in your bibliography. Note the tension with the licence section. The permission text says you may remove the footer's copyright notice without breaking the licence, and the request list asks you to keep a different footer element. Nothing about the QR code is a licence condition, so the ask is a favour rather than an obligation, and a commercial deployment that has taken the licence section at its word will not have kept it. That is the pattern to watch here generally: the page mixes legal permission, community requests and paid services in the same voice.

Two free features became paid coin services inside five months

The changelog is organised by year with a date, a type, a description and an image column, and it is long enough to be a genuine engineering record. Two entries in the most recent year describe a business change rather than a feature. In May, the endpoint for downloading test data and the page that parses run errors and wrong answers were both upgraded to paid services, charged in an in-app virtual currency, and marked with a coin symbol in the changelog. A month earlier the currency itself was introduced: users earn coins by solving problems, administrators can award them, administrators can spend them on offline rewards, and anyone doing secondary development can add features that spend them. Earlier still, a paid problem bank was added for prepaid downloads. So the trajectory inside one release year is free, then earn, then spend, then two endpoints behind a paywall. For an institution budgeting a deployment, that is the line item most likely to matter.

Release tags alternate two date formats and one is named after a typhoon

There are three releases in the recent list and they are named three different ways. Two use a two digit year, a month and a day. One uses all four digits for the year. One carries a festival greeting as its title, which is a nice touch and tells you how the maintainer titles releases. One is named after a tropical cyclone, which tells you something else: releases track events as well as features. The third title is the most informative of the three, because it lists the distributions and architectures that release covers, naming four architectures including one non-x86 target. That matches an entry from the previous year recording initial support for that same architecture family. Two housekeeping details sit underneath all of this. Continuous integration is configured for a different Git hosting service than the one the repository is on, and an Android package file sits at the repository root. Also worth noting: the newest release is from late August, the most recent changelog entry is from May, and the last commit is from the start of October.

Editorial conclusion

HUSTOJ suits a school, training class or regional contest that needs a judge it can host and modify itself, and that reads Chinese documentation without difficulty. Four things to know before deploying it. The licence section is the project's own reading of what counts as distribution, and it permits removing the footer credit, so read it before you rely on it and take your own advice on the question. The container declares one volume while the commented out line above it names the five that matter, including the database directory. The changelog shows free features becoming paid ones, so a deployment that assumes a free download endpoint or free error explanation will change. And the newest release tag is from August while the last changelog entry is from May, so the tagged build and the documented behaviour may differ.

Frequently asked questions

What is HUSTOJ?

A long-running open source online judge for programming training, aimed at competitive programming and at the national school exam syllabus, built on a language runtime, a web server, a relational database and Linux, with its own problem bank and a low barrier to secondary development. It installs on several distributions, ships a container image and a live image, and has an in-repository wiki plus a separate documentation site and FAQ.

What licence is HUSTOJ under?

GPL version 2, and the page spells out at length how the maintainer reads it. The licence covers the original code only, with borrowed components keeping their own terms. The only substantive requirement is providing source when you distribute, defined as installing a derived product on a customer's server. The page states that offering the derived work as a hosted service on your own servers is not distribution, and that calling the system's functions over a database or an HTTP interface does not bring your code under the licence.

How do I install HUSTOJ?

The page lists install paths for several Linux distributions, marks one of them as the recommended option for beginners because the packaged software is newest there, and also offers a container path and a live image. It asks you to read a prerequisites page first, and for campus networks there is a separate guide. One instruction is specific to cloud virtual machines: remove the cloud security agent that the machine image ships with, which otherwise interferes with the install.

What are the notable HUSTOJ features?

Several appear in the changelog rather than in a feature list: interactive problem judging against a test harness header, partial scoring with configurable markers, a per-test-data configuration file that overrides system judging settings, running test data in the browser through a WebAssembly build of a SQL engine to take load off the server, an option for contests to score only the final submission, and a WebAssembly-based browser test runner. It also has account expiry dates with a far future default for self-registered accounts, and it lights a star next to a user's rank if that person's account on the code hosting site matches.

How does HUSTOJ support remote help?

The page offers paid services including remote assistance, server rescue and technical consulting through a messaging contact, and it asks anyone wanting remote assistance to install a third-party remote desktop tool in advance or to have a publicly reachable SSH account ready. It also lists an official chat group and a paid problem bank. Anyone accepting that arrangement should understand that it grants someone else access to the machine running the judge.

Official sources

  1. License: GPL-2.0
  2. Project website
  3. README
  4. Releases
  5. zhblue/hustoj 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/zhblue-hustoj.svg)](https://hysenlabs.com/projects/zhblue-hustoj)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/zhblue-hustoj.svg)](https://hysenlabs.com/projects/zhblue-hustoj)

Was this useful?