Coral: self-hosted TypeScript commenting platform for news publishers
A better commenting experience from Vox Media
At a glance
- What is it?
- Coral is a TypeScript commenting platform from Vox Media that news publishers host themselves, with React on the client, Node.js and GraphQL on the server, and MongoDB plus Redis as required infrastructure. Moderation controls, comment migration, and multi-site support are built in, but setup complexity and infrastructure maintenance fall entirely on the operator.
- Who is it for?
- Coral suits news publishers who need full control over comment data and moderation, are willing to self-host Node.js, MongoDB and Redis, and have engineering support for maintenance and upgrades. Skip it if no-infrastructure commenting is the goal, since every component runs on your own servers and Docker Hub hosts the official image at coralproject/talk.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 37 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 11, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Coral rethinks moderation and comment display for journalism sites that own their data
Coral is a TypeScript commenting platform built by the Coral team at Vox Media and designed for news publishers who need moderation controls and conversation data they host themselves. Its repository topics include journalism, which signals the intended audience clearly. React handles the frontend, Node.js runs the server, and a GraphQL API connects them. A locales/ directory exists at the top level, indicating internationalization support, though the specific languages are not listed in the README.
Moderation, comment display and conversation are the three areas the project describes itself as rethinking. Pre-launch community setup is a named responsibility: the Community Guides at guides.coralproject.net/start-here/ cover setting up community rules before going live. Comment migration from another system and integration with an existing registration platform are services the commercial support offering covers, which implies both features exist and that configuring them without assistance is non-trivial.
WordPress integration lives in a wordpress/ directory at the repository root. Multi-site configuration has a dedicated test directory (multi-site-test/). A separate INDEXES.md file at the root documents the MongoDB indexes, which is a practical signal that index management requires explicit attention for operators running the database themselves.
Two required infrastructure services: Redis 7.2.5 on port 6379 and MongoDB 8.0.3 on port 27017
Coral requires Redis and MongoDB before the application itself can start. The docker-compose.yml at the repository root defines both services:
services:
redis:
image: redis:7.2.5
container_name: coral-redis
restart: always
ports:
- "6379:6379"
mongo:
image: mongo:8.0.3
container_name: coral-mongo
restart: always
ports:
- "27017:27017"Redis is pinned at version 7.2.5 and MongoDB at 8.0.3. Both services run with restart: always, meaning they restart automatically after a crash or host reboot. The docker-compose.yml defines no volume mounts, so data would not survive a container removal. Adding named volumes to each service is a configuration step the provided file does not include, and any production deployment would need to add them to avoid data loss on container restart or upgrade. The docker-compose.yml also defines only the infrastructure services and includes no service entry for the Coral application itself, so it is a starting point for a full stack definition rather than a complete one.
Dockerfile builds on node:18-alpine, sets an 8GB heap limit, and runs as the non-root node user
The Dockerfile builds from node:18-alpine and sets three Node.js environment flags before any code runs:
ENV NODE_OPTIONS="--max-old-space-size=8192 --openssl-legacy-provider --no-experimental-fetch"--max-old-space-size=8192 allocates 8GB of V8 heap, reflecting the memory cost of building the React client. --openssl-legacy-provider enables the legacy OpenSSL provider that Node.js 17 and later removed by default, required for older cryptographic dependencies in the build chain. --no-experimental-fetch disables Node's experimental fetch API; the flag is present to avoid conflicts when a project bundles its own fetch polyfill alongside a Node version that also ships an experimental one.
Build dependencies installed in the Alpine image include g++, make, git, python3, py3-pip, py3-setuptools and linux-headers. pnpm is installed globally at version 8.14.3. Using node:18-alpine as the base means no build tools are pre-installed, which is why g++, make, linux-headers and the Python packages must be installed explicitly before any application code compiles. The application runs as the non-root node user, following the Node Docker best practices guide cited in the Dockerfile. An SSH workaround rewrites GitHub SSH URLs to HTTPS during the build using git config, since the build container has no SSH key available.
Four sub-packages build in sequence, with GraphQL schema generation before the client compiles
The monorepo contains four sub-packages that build in a fixed order: config, common, client and server. Each runs pnpm install --frozen-lockfile to lock its dependency tree. Before any other build step, the server sub-package runs pnpm run generate to produce GraphQL schema types that common/ depends on at compile time.
After server generates types, the build sequence proceeds: config builds first, then common, then client. The client step includes pnpm prune --prod to strip development dependencies from its node_modules before packaging, reducing the final image size. Server builds last.
For releases, scripts/version.sh automates version bumps across all sub-packages:
sh scripts/version.sh MAJOR.MINOR.VERSIONThis script runs npm version x.y.z against each child repository, updating all package.json files in one step rather than requiring manual edits in each sub-package. An incorrect version argument format could leave the sub-packages at inconsistent versions, so verifying with MAJOR.MINOR.VERSION syntax matching the example (such as 8.5.0) is the safe approach. The build order matters because each sub-package's types are available to the next one in sequence; skipping or reordering a step would break the TypeScript compilation.
Self-hosting means owning MongoDB, Redis and Node.js maintenance, which hosted alternatives avoid
Coral runs on infrastructure you provision and maintain. MongoDB, Redis, the Node.js process, and the container runtime all require ongoing attention: schema migrations between versions, dependency security patches, and capacity planning as comment volume grows. That is the operational cost the project's self-hosted model places on the operator.
Hosted commenting services take the opposite approach. They run on their own servers, require no database maintenance, and charge per site or view. Comment data and moderation history live on those servers rather than in your own MongoDB instance. For news publishers whose comment archive represents years of reader engagement, that data ownership is often the deciding factor. The difference in approach is infrastructure control versus infrastructure elimination, and Coral is explicitly the former.
Setup documentation lives at docs.coralproject.net. Commercial support covering setup, comment migration, registration platform integration and bespoke installs is available through the pricing page at coralproject.net/pricing/. Code of conduct, contributing guidelines and security policy are in CODE_OF_CONDUCT.md, CONTRIBUTING.md and SECURITY.md at the repository root.
GraphQL schema types generate at build time, and the API surface is not documented in the README
Coral's server exposes a GraphQL API, and the pnpm run generate step that runs before the client build produces typed schema definitions from it. Those types flow into the common/ package, which means the client and any downstream integration work against a generated contract rather than manually written types.
No API reference appears in the top-level repository files. The documentation at docs.coralproject.net is the documented entry point for API details and integration guidance. For teams building a custom commenting widget or integrating Coral with a CMS other than WordPress, the absence of an in-repo API reference means the external documentation site is the only resource listed for that path. The Dockerfile comment for the generation step reads "Generate schema types for common/ to use", confirming that the generated output is a compile-time dependency shared across sub-packages rather than a runtime artifact.
The repository also includes a docker-compose.yml limited to infrastructure services (Redis and MongoDB), with no service definition for the Coral application itself in the provided portion. A full docker-compose configuration for running the complete stack is not included in the top-level file provided in the repository.
Apache-2.0 confirmed in README despite GitHub's Other classification, with rapid patch releases in mid-2026
GitHub classifies the licence as Other, but the README explicitly states "Coral is Apache-2.0 licensed" and links the LICENSE file. Apache-2.0 is a permissive licence that allows redistribution with attribution. Reading the LICENSE file at the repository root is the required step before any redistribution or embedding in a commercial product.
Version v9.11.8 was released on 2026-07-07, v9.11.7 on 2026-06-24, and v9.11.6 on 2026-06-22. Three releases in three weeks indicates an active patch cycle during that period. A push to the develop branch was recorded on 2026-09-04. Frequent patch releases mean that operators who pin to a specific Docker tag should check the release notes between versions before upgrading, since the gap between v9.11.6 and v9.11.8 covers two separate patch cycles.
Docker Hub hosts the official image at coralproject/talk. Verifying that the Hub tag corresponds to the GitHub release version before pulling is worth doing, since Docker Hub and GitHub releases can fall out of sync during a rapid release period.
Editorial conclusion
Coral suits news publishers who need full control over comment data and moderation, are willing to self-host Node.js, MongoDB and Redis, and have engineering support for maintenance and upgrades. Skip it if no-infrastructure commenting is the goal, since every component runs on your own servers and Docker Hub hosts the official image at coralproject/talk. Before deploying, confirm that your environment can supply the 8GB of V8 heap that the Dockerfile's NODE_OPTIONS allocates, and verify that the Docker Hub tag matches the GitHub release version before pulling.
Frequently asked questions
What is Coral (coralproject/talk)?
Coral is a self-hosted TypeScript commenting platform from Vox Media, designed for news publishers who want moderation controls and full ownership of their comment data. It uses React, Node.js, GraphQL, MongoDB and Redis.
What infrastructure does Coral require?
Coral requires MongoDB 8.0.3 and Redis 7.2.5 as infrastructure services, both defined in the docker-compose.yml at the repository root. MongoDB listens on port 27017 and Redis on port 6379.
What version of Node.js does Coral use?
Coral's Dockerfile builds on node:18-alpine. It also sets --max-old-space-size=8192 and --openssl-legacy-provider in NODE_OPTIONS, reflecting the memory needs of the client build and a legacy OpenSSL dependency.
Is Coral open source?
Yes. The README states that Coral is Apache-2.0 licensed and links the LICENSE file in the repository. GitHub classifies the licence as Other, but the README text and the LICENSE file both confirm Apache-2.0.
Does Coral support WordPress?
A wordpress/ directory exists at the top level of the repository, indicating WordPress integration is included. The README does not document the WordPress integration steps; the documentation at docs.coralproject.net is the stated reference for setup guidance.
Official sources
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.
[](https://hysenlabs.com/projects/coralproject-talk)