Open-source project
KunMoe/kun-touchgal-next avatar
KunMoe/kun-touchgal-next

kun-touchgal-next: the Next.js rewrite behind a Galgame download and forum site

TouchGal 是一个一站式 Galgame 文化社区。提供Galgame 论坛、Galgame 下载等服务。承诺永久免费, 高质量。为Galgame 爱好者提供一片净土!

824 stars43 forksTypeScriptAGPL-3.0

At a glance

What is it?
A TypeScript Next.js 15 application for a Galgame community, with Prisma and PostgreSQL for data, Redis for caching, optional Meilisearch for search, S3 for patch archives and image hosting, deployed under pm2 and licensed AGPL-3.0.
Who is it for?
Adopt kun-touchgal-next if you want to run a Galgame forum and patch download service and want a modern Next.js 15 codebase with Prisma, Redis, S3 and a working search pipeline rather than a legacy PHP board.
Can I use it commercially?
Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
Is it still maintained?
Yes. The repository last received commits 3 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

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

A forum and patch site, rewritten on the modern Next.js stack

TouchGal is a one-stop Galgame culture community offering a forum and game downloads, with a stated promise of being permanently free and high quality. The repository in question is the `next` generation of it, the second rewrite in a line that starts from a project called kun-galgame-patch-next.

The stack is legible from the package metadata and the topic list, which name Next.js 15, React 19, Prisma, PostgreSQL, Redis, Tailwind CSS v4, Turbopack, zustand, zod, argon2, JWT, the AWS S3 client, Milkdown as the rich text editor, Cloudflare Workers, and ESLint and Prettier for tooling.

Two things about the shape of the codebase are worth noticing before the feature list. First, `package.json` marks the package as private, so this is an application repository rather than a library you install. Second, the script list is unusually complete for a community site: it covers search indexing (`search:init`, `search:sync-all`, `search:reconcile`, `search:engine`, `search:setup`), a comment HTML backfill, sitemap generation, a postbuild step, and dedicated deploy scripts for install and build.

Those search and deploy scripts are the honest signal about what kind of project this is. A site serving patch archives and forum content needs to keep a search index in sync with the database, needs to migrate old comment markup without losing it, and needs a repeatable deployment path. The package version is 1.0.7.

The project also ships an `AGENTS.md` and a `CLAUDE.md` at the top level, which are the current convention for instructions aimed at coding agents working in the repository.

Running it locally needs four services and a filled in env file

The documentation asks for Node.js, pnpm, PostgreSQL and Redis installed locally, then gives four steps: clone the repository, create a `.env` file from the `.env.example` at the project root and fill in the variables, run `pnpm prisma:push` on the first run to create the local database, and then start the app with `pnpm dev`.

The dev script binds to a fixed address and port:

bash
pnpm dev

which the package scripts expand to `next dev --hostname=127.0.0.1 --port=3000`. A webpack variant exists alongside it as `dev:webpack`, and the production build is `NODE_ENV=production next build`.

The configuration surface is where most of the work is. The example file defines a PostgreSQL connection string, the site URL, separate patch address variables for development and production, Redis host, port and password, JWT issuer, audience and secret, a two factor backup pepper, a full set of OIDC provider variables for an external identity provider, an email service block with SMTP host, port, account and password, and the S3 storage credentials, bucket, endpoint, region and public URL, plus the image host settings.

The values shipped in that file are placeholders. They are syntactically valid, which is exactly why the documentation tells you to fill them in yourself, and the S3 access key and secret are obviously placeholder strings. The JWT secret and the Redis password in particular must be replaced before anything runs, because the example values are committed to the repository and therefore public.

Search is an optional sidecar service, not a hard dependency

The most interesting piece of infrastructure in the repository is the search layer, because it is deliberately optional and its lifecycle is managed through pnpm scripts rather than Docker Compose alone.

The compose file defines a single service, Meilisearch, pinned to the `getmeili/meilisearch:v1.15` image, named `kun-meilisearch`, set to restart unless stopped, and bound to `127.0.0.1:7700` so it only listens on the loopback interface. Data persists in a named volume `meili_data`, and the environment sets `MEILI_ENV: production` and `MEILI_NO_ANALYTICS: 'true'`.

The master key handling is the detail worth copying. The compose file requires `MEILISEARCH_ADMIN_API_KEY` to be set, failing with a message that says it must be configured in `.env` or started through `pnpm search:engine`. A comment explains why it is not read from `.env` directly by compose: the value is read from the project root `.env` by `scripts/search/engine.ts` and injected through the process environment, so that formatting differences such as `KEY = "value"` cannot leave the key empty.

That is a small but real hardening decision. Compose's own `.env` parsing and a TypeScript parser disagree about spacing around `=`, and a search index that starts with an empty admin key fails in a confusing way.

The scripts cover the full lifecycle: `pnpm search:engine` starts the engine and waits for a health check, `pnpm search:setup` runs the first-time full flow, and `pnpm search:init`, `pnpm search:sync-all` and `pnpm search:reconcile` handle initialising, bulk syncing and reconciling the index against the database.

Storage is split three ways: database, object store, image host

The configuration shows three separate storage concerns, each with its own set of variables.

PostgreSQL holds the relational data, reached through `KUN_DATABASE_URL` with the `psql` connection scheme, and managed through Prisma with `prisma.config.ts` at the root and a `prisma/` directory holding the schema and migrations. The `migration/` directory at the top level sits alongside it, which suggests migration artefacts are tracked separately from the Prisma schema history.

S3-compatible object storage holds the patch archives. The variables cover the access key id, secret access key, bucket name, endpoint, region and a public URL served from a separate domain, and the AWS SDK client and request presigner are dependencies, which points to browser uploads using presigned URLs rather than proxying file bytes through the application.

A third host is configured separately for images, with both a host and a URL variable pointing at an image bed domain.

Redis is configured with host, port and password, where an empty password is the documented option for a local instance with none. The JWT block sets an issuer, an audience and a secret, with the documentation noting the development values need no change, and the OIDC block adds an issuer URL that must carry an `/oidc` path prefix, a JWKS JSON string generated by a script, cookie signing keys for rotation, and a secret encryption key for storing client secrets.

The result is a fairly demanding local environment. PostgreSQL and Redis are required; Meilisearch is optional; the mail, object storage and image services are external and, in the shipped configuration, point at one operator's domains.

Deployment runs under pm2 with scripts for install and build

The production story is pm2 plus an ecosystem config file. The `start` script runs `pm2 startOrRestart ecosystem.config.cjs` and the `stop` script runs `pm2 delete ecosystem.config.cjs`. There is also `ecosystem.config.cjs` at the top level describing the process.

Two dedicated scripts handle the deployment itself: `deploy:install` and `deploy:build`, both written in TypeScript and run through esno, so the deployment procedure is code rather than a runbook of shell commands. `build:sitemap` generates the sitemap with a separate script, and `postbuild` runs a postbuild script after the Next.js build.

Some scripts point at data repair work rather than steady state. `backfill:comment-html` exists to backfill comment HTML, which is the kind of one-off migration script that accumulates in a project where the editor changed at some point.

Testing and quality tooling is also wired up. `test` runs `vitest run` with `vitest.config.ts` at the root and a `__tests__/` directory, `lint` and `lint:fix` run ESLint through `eslint.config.mjs`, `format` runs Prettier with `.prettierrc.json` and `.prettierignore`, and `typecheck` runs `tsc --noEmit`. The `patches/` directory and `pnpm-workspace.yaml` indicate patched dependencies, and `instrumentation.ts` and `proxy.ts` sit at the root for Next.js runtime hooks.

One piece of repository etiquette is stated firmly. If your change touches the source, you must run the project successfully locally and test it before opening a pull request, because it seriously slows the code audit otherwise.

AGPL-3.0 and a fork lineage that has to be credited

The licence is AGPL-3.0, recorded as `AGPL-3.0-only` in the package metadata with the LICENSE file at the root. The documentation adds a specific requirement on top of the licence text: any modification you distribute must state the original repository and the author's address.

The project is also explicit about where it came from. It was modified from kun-galgame-patch-next, whose repository is linked in the documentation, and the change of name reflects that this is the second iteration rather than a fresh start.

For anyone considering running this, two consequences of AGPL-3.0 deserve attention. The copyleft reach of AGPL extends to network use: if you modify the software and offer it to users over a network, the source of your modified version has to be offered to them too. And the attribution requirement is stated by the project itself, so it is not a detail you can ignore by arguing about interpretation.

This is not legal advice, and the practical position for most readers is different depending on what they intend. Running the software as a service for your own community without modifying it is a different question from forking it, and the answer for a specific case needs reading the licence text and, if it matters, asking a lawyer.

The project also routes communication through Discord for bug reports and a Telegram group for web development discussion, with Node.js, Nuxt, Next.js, SvelteKit and SolidStart named as the areas of interest there.

Editorial conclusion

Adopt kun-touchgal-next if you want to run a Galgame forum and patch download service and want a modern Next.js 15 codebase with Prisma, Redis, S3 and a working search pipeline rather than a legacy PHP board. Do not adopt it unmodified if your deployment cannot reach the mail, S3 or image hosts it expects, since the configuration is written around one operator's infrastructure, and note the AGPL-3.0 obligation to name the original repository and author when you redistribute a modified version. Verify first that you can replace the example credentials in .env.example for PostgreSQL, Redis, JWT, OIDC, SMTP and S3 before any of the features work.

Frequently asked questions

How do I run kun-touchgal-next locally?

You need Node.js, pnpm, PostgreSQL and Redis installed. Clone the repository, copy .env.example to a .env file and fill in the variables, run `pnpm prisma:push` to create the local database, then start the app with `pnpm dev`, which runs next dev on 127.0.0.1 port 3000.

Is Meilisearch required to run the site?

It is optional. The compose file ships a single Meilisearch service bound to 127.0.0.1:7700 with a persistent meili_data volume, and the scripts search:engine, search:setup, search:init, search:sync-all and search:reconcile manage its lifecycle.

What services does the .env file configure?

PostgreSQL through KUN_DATABASE_URL, Redis with host, port and password, JWT with issuer, audience and secret, an OIDC provider block with issuer, JWKS, cookie keys and a secret encryption key, an SMTP email service, S3 storage credentials for patch archives and a separate image host.

Under what licence is kun-touchgal-next released?

AGPL-3.0, recorded as AGPL-3.0-only in package.json. The project also asks that any distributed modification state the original repository and the author's address, and notes that it was modified from kun-galgame-patch-next.

How does the project handle testing and code quality?

The scripts cover vitest for tests, ESLint for linting, Prettier for formatting and tsc --noEmit for type checking, with separate deploy:install and deploy:build scripts run through esno. Contributors are asked to run the project locally and test their change before opening a pull request, to keep code review workable.

Official sources

  1. Issues
  2. KunMoe/kun-touchgal-next on GitHub
  3. License: AGPL-3.0
  4. Project website
  5. README
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/kunmoe-kun-touchgal-next.svg)](https://hysenlabs.com/projects/kunmoe-kun-touchgal-next)

Was this useful?