Artalk: a Go comment backend with a 40KB Vanilla JS client
🌌 Your Self-hosted Comment System. | 自托管评论系统
At a glance
- What is it?
- Artalk splits a self-hosted comment system into a Go server and a framework-agnostic browser client that initialises with four keys. The split is what makes it portable, and also what decides where it fits.
- Who is it for?
- Adopt Artalk if you run several sites or blogs and want one Go binary plus a Docker volume holding all comment data, with a client that does not care which framework renders your pages. Do not adopt it if you want comments to live as files inside your static site repository, or if you need the moderation workflow to survive a server that is down.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 5 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The problem Artalk solves: comments that belong to you, on pages that are not yours to control
A hosted comment service puts a third party between your readers and your content. The widget loads from someone else's domain, the thread lives in someone else's database, and when the service changes its pricing or shuts down, the discussion does not follow you. Artalk is aimed at the person who has already decided that is unacceptable: someone running a blog, documentation site, or small web application who is willing to operate a server process in exchange for owning the comment table.
The project describes itself as a self-hosted comment system with privacy as a priority, and the repository is written primarily in Go with an MIT licence. The audience is narrower than "anyone with a website". You need a host that can run a long-lived process or a container, a domain or subdomain for the API, and some way to persist a data directory. If your site is a static bundle on a CDN with no backend at all, Artalk does not remove that requirement. It relocates it: one small server, one volume, and a client script that talks to it over HTTP.
Two halves: a Go server you deploy and a client you initialise with four keys
The architecture is a clean client-server split. The server is a Go binary distributed as a Docker image (artalk/artalk-go), as binary releases, through go install, and through Linux distribution package managers, according to the README's installation section. The client is a browser bundle published to npm as artalk, described in the README as roughly 40KB and written in pure Vanilla JS, which is why the topics list includes Vue, React, and SolidJS: those are integrations around the same client, not separate implementations.
Data flow is conventional. The browser loads the client, the client calls the server over HTTP for the comment list and for posting, and the server persists everything into its data store. What matters for adoption is where the configuration lives. Site identity is a server-side concept: the Docker example sets ATK_SITE_DEFAULT and ATK_SITE_URL as environment variables, and the browser side repeats the site name in Artalk.init. The pageKey parameter, shown in the README as a path like /2018/10/02/hello-world.html, is what ties a comment thread to a specific page. Get the site name or the page key wrong and comments appear to vanish, because they are attached to a different thread than the one you are rendering.
The feature list points at a multi-site model with site isolation and centralized management, which is the design decision that shapes everything else. One server instance can hold threads for several sites, and the admin surface manages them together. Self-hosting one instance for one blog is the simple case. Self-hosting one instance for five blogs is the case the project was built around.
Getting it running: one docker run, one Artalk.init call
The README gives a complete deployment in a single command. It runs the container detached, names it artalk, maps host port 8080 to container port 23366, mounts a local data directory at /data, and sets four environment variables: TZ for the timezone, ATK_LOCALE for the interface language (en in the example), ATK_SITE_DEFAULT for the default site name, and ATK_SITE_URL for that site's URL.
The port mapping is worth reading twice. The container listens on 23366, not 8080, so the left-hand side of -p is the only number you choose freely. The volume mount is the part that decides your backup story: everything the server persists goes under /data, so a bind mount to a directory you already back up is the difference between a restorable instance and a lost comment history.
The client side is equally short. The README's TypeScript example calls Artalk.init with an el selector for the container element, a site string that must match ATK_SITE_DEFAULT, a server URL, and a pageKey for the current page. The el value in the example is '#Comments', which means the page needs an element with that id before the script runs. Everything beyond these four keys (nesting depth, list sorting, voting, dark mode, i18n, lightbox, LaTeX, lazy loading) is documented under frontend configuration, and the backend side covers email notification, push notification, captcha, moderation, image upload, and IP region lookup. The README does not enumerate the config keys for those features, so treat the documentation site as the source for anything past the initial deployment.
The operational cost the README does not price in: email, push, captcha and region lookup
Artalk's feature list reads like a list of external dependencies once you look past the names. Email notification is described as supporting various sending methods, which means an SMTP or API credential for a mail provider. Diverse push covers multiple push methods, which means at least one bot token or webhook secret. Captcha covers various verification types, which means a third-party verification service or a self-hosted one. IP region display requires a geolocation source. None of these are heavy, but each is a credential you now store on your server and a dependency that can fail independently of the comment system.
The upgrade path is the other recurring cost. The repository ships tagged releases and a nightly build, and the feature list mentions version checking and one-click upgrade. A nightly channel existing alongside stable releases tells you the project moves between tags, and the gap between v2.9.1 in September 2024 and v2.10.0 in July 2026 is a reminder that a self-hosted comment system is a component you will revisit rather than install once. The README points to a CHANGELOG.md and a data migration guide under the transfer documentation, which is where you should look before any major version jump. Backing up /data before an upgrade is not optional advice here; it is the only copy of your threads.
The licence is MIT, which is permissive and places few obligations on how you run or modify the server. That is a statement about the licence text, not legal advice about your situation.
Where Artalk is the wrong choice
The clearest failure mode is a static site with no willingness to run a process. Artalk needs a reachable server URL for Artalk.init, and if your publishing pipeline only emits HTML to a CDN, you have to add a host, a container runtime, and a TLS-terminating proxy in front of it. That is a real amount of infrastructure for a comment box, and the project does not pretend otherwise.
The second case is a single-author site with low comment volume and a preference for comments as files. Artalk stores threads in its own data store behind an API. If your mental model is "comments are Markdown files committed next to posts, and a build step renders them", Artalk inverts that model. There is a data migration path documented, so moving in or out is contemplated, but the daily workflow is database-first, not repository-first.
The third case is moderation that must work while the server is down. The moderation and spam interception features live in the server. If the process is not running, nothing is being filtered. A site that cannot tolerate a window of unfiltered comments needs either an external filter in front of the API or a different posture toward availability.
Finally, the multi-site design is a strength that becomes a hazard if you ignore it. Because site identity is set on both sides, a mismatch between the server's ATK_SITE_DEFAULT and the client's site value produces an empty thread with no obvious error. That is a configuration bug that looks like data loss.
How it differs from Isso, and why the language choice is the real difference
The natural comparison is Isso, the long-standing self-hosted comment server written in Python. Both are self-hosted, both expose an HTTP API to a JavaScript client, and both target the same person: someone with a blog who does not want a hosted comment provider. The difference is in the runtime and the deployment surface. Isso is a Python package you install into an environment and run behind a WSGI server, with SQLite as its usual store. Artalk ships a compiled Go binary and a Docker image, so the deployment unit is a container or a single executable rather than an interpreter plus dependencies.
That distinction has practical consequences. A Go binary has no virtualenv, no Python version to pin, and no dependency resolution at deploy time; the container image bundles the runtime. It also means you cannot patch Artalk's behaviour by editing a Python file in place, which is the trade-off Isso users sometimes rely on. The frontend split runs the other way too. Artalk's client is a single Vanilla JS bundle with framework integrations layered on top, while Isso's client is a script you drop into the page. Neither is better in the abstract; if your team already operates Python services, Isso adds nothing new to your stack, and if you would rather ship one static binary, Artalk does.
A second axis is the multi-site model. Artalk's documentation describes site isolation with centralized management, which suggests one instance serving several sites. Isso's model is closer to one instance per site. If you run a handful of small sites, consolidating them behind one Artalk server removes duplicated processes. If you run one site and want the smallest possible footprint, that capability is unused weight.
Editorial conclusion
Adopt Artalk if you run several sites or blogs and want one Go binary plus a Docker volume holding all comment data, with a client that does not care which framework renders your pages. Do not adopt it if you want comments to live as files inside your static site repository, or if you need the moderation workflow to survive a server that is down. Before committing, verify three things: that your database choice is listed in the server config documentation, that ATK_SITE_DEFAULT and ATK_SITE_URL match the site name and origin you pass to Artalk.init exactly, and that your host has outbound access for the email and push notification features you plan to enable.
Community notes