Deploy LanguageTool
Grammar, style and spell checking API for more than 30 languages
MySQL
Just deployed
/var/lib/mysql
Just deployed
languagetool
Just deployed
Deploy and Host LanguageTool on Railway
LanguageTool is an open-source proofreading engine that finds grammar, style, punctuation and spelling mistakes in more than 30 languages, and it powers the LanguageTool browser add-ons, the LibreOffice integration and dozens of editor plugins. Unlike a spell checker it reasons about context, catching confused words, agreement errors and awkward phrasing a dictionary lookup never will. Teams self-host LanguageTool to get that quality without sending drafts or customer documents to a third-party writing service.
Deploy LanguageTool on Railway and you get the complete HTTP API, not a trimmed demo. The template runs three services: languagetool is the Java API server on the private network, MySQL stores API keys and per-account dictionaries, and gateway is the public entry point — a Caddy reverse proxy that serves a browser console and rewrites X-Forwarded-For so the per-IP rate limiter sees real callers rather than the platform edge. Self-host LanguageTool this way and the API starts closed: anonymous requests are rejected.

Getting Started with LanguageTool on Railway
Deploy the template, wait for all three services to go green, then open the gateway service's public URL. You land on a console that reports the running LanguageTool version once it reaches the API. Paste the credentials first: the username and API key are the LT_API_USERNAME and LT_API_KEY variables on the languagetool service, and the console keeps them in your browser only. Type a paragraph, pick a language — or leave it on automatic detection, handled by the bundled fastText model — and press Check text. Each finding comes back with the rule that fired, the sentence context and clickable replacements; clicking one rewrites your text and re-runs the check. Then add a word such as a product name to the personal dictionary and check again: it stops being flagged, because that word is now a row in MySQL tied to your account. That round trip exercises all three services at once.

About Hosting LanguageTool
LanguageTool combines a rule engine, hand-written grammar patterns and morphological dictionaries into one JVM service that answers POST /v2/check with a JSON list of matches. Self-hosting matters when the text is confidential, when you need volume without per-seat pricing, or when you want your own terminology.
- More than 30 languages, including variants such as
en-US,en-GB,de-DEandpt-BR - Context-aware grammar and style rules, with a stricter
pickylevel - Automatic language detection via a bundled fastText model
- Per-account dictionaries through
/v2/words,/v2/words/addand/v2/words/delete - API-key authentication, per-IP request limits and a maximum text length
languagetool does the analysis and holds no local state, so it restarts without losing anything. MySQL holds the two tables the server reads: accounts with their API keys, and the words each account told the checker to ignore. gateway is the only service with a public domain.
Why Deploy LanguageTool on Railway
Railway removes the setup work that makes self-hosting a grammar server unattractive.
- Managed MySQL, provisioned and wired to the API server automatically
- No JVM tuning: the heap is sized from the container's real memory limit
- HTTPS, a public domain and health checks configured out of the box
- API-key authentication enforced from the first request
Common Use Cases for Self-Hosted LanguageTool
- Editorial pipelines — proofread articles or release notes in CI and fail a build on unresolved issues
- Support tooling — check agent replies before sending, without routing conversations through an external service
- CMS and editor integrations — back a "check my text" button in your own app, or point plugins at an endpoint you control
- Regulated environments — proofread inside your own network, where a hosted checker is not allowed
LanguageTool vs Grammarly and Other Grammar Checkers
| LanguageTool (self-hosted) | Grammarly | |
|---|---|---|
| Self-hosting | Yes, LGPL-2.1 | No |
| Languages | 30+ | English only |
| API access | Open JSON API | Enterprise only |
| Per-seat cost | None | From ~$12/user/month |
| Custom dictionary | In your database | Vendor cloud |
Grammarly is stronger at English rewriting; LanguageTool wins on language coverage, data control and cost once more than a few people need it.
Dependencies for LanguageTool on Railway
- languagetool — built from
erikvl87/languagetool, the community image packaging each upstream release - gateway —
caddy:2-alpine, the public reverse proxy and console - MySQL —
mysql:9.4, the account and dictionary store
Environment Variables Reference
| Variable | Service | What it does |
|---|---|---|
LT_API_USERNAME | languagetool | Username callers send as username |
LT_API_KEY | languagetool | Secret callers send as apiKey |
langtool_anonymousAccessAllowed | languagetool | false closes the API; true opens it |
langtool_requestLimit | languagetool | Requests allowed per client IP per period |
langtool_maxTextLength | languagetool | Maximum characters in one request |
langtool_languageModel | languagetool | Directory of n-gram data, if you add a volume |
Java_Xmx | languagetool | Overrides the derived JVM heap size |
Deployment Dependencies
- Source repository: github.com/gridalpha/languagetool-railway
- Upstream project: github.com/languagetool-org/languagetool
- API documentation: languagetool.org/http-api
- Base image: hub.docker.com/r/erikvl87/languagetool
Hardware Requirements for Self-Hosting LanguageTool
| Minimum | Recommended | |
|---|---|---|
| CPU | 1 vCPU | 2–4 vCPU |
| RAM | 1 GB | 2–4 GB for the API server |
| Storage | None for the API server | 5 GB for MySQL |
| Runtime | Java 17 | Java 17 |
Memory is the number that matters: LanguageTool loads dictionaries and rule sets per language on first use, so one language fits in 1 GB while a multilingual server wants 4 GB.
Self-Hosting LanguageTool with Docker
To run the same image locally, start the community container on port 8010:
docker run --rm -p 8010:8010 \
-e Java_Xms=512m -e Java_Xmx=2g \
-e langtool_pipelineCaching=true \
erikvl87/languagetool
Any LanguageTool client speaks the same endpoint. This checks one sentence, using the credentials from the Railway variables:
curl -s https://your-app.up.railway.app/v2/check \
--data "language=en-US" \
--data-urlencode "text=She dont know weather to chose the blue one." \
--data "username=apiuser" \
--data "apiKey=YOUR_LT_API_KEY"
Editor integrations that accept a custom server URL — LTeX for VS Code, the Obsidian plugin, Joplin, Nextcloud Text — point at the same origin.
How Much Does LanguageTool Cost to Self-Host?
LanguageTool's server is free and open source under LGPL-2.1, so there is no licence fee and no per-seat charge however many people or services call it. Hosted LanguageTool Premium runs from roughly $5 to $25 per user per month; self-hosting replaces that with infrastructure cost alone. On Railway you pay for the API server's memory, the proxy and the MySQL volume. Premium-only rules and AI rewriting are not in the open-source build.
FAQ
What is LanguageTool? An open-source proofreading service that checks text for grammar, style, punctuation and spelling errors in over 30 languages, exposed as a JSON HTTP API used by browser add-ons, office suites and editor plugins.
What does this Railway template deploy? Three services: the LanguageTool API server, a MySQL database holding API keys and dictionaries, and a Caddy gateway publishing the API and a browser console on one HTTPS domain.
Why does this template include a database?
LanguageTool's open-source server reads accounts and their API keys from MySQL — that lookup is what makes langtool_anonymousAccessAllowed=false possible — and the same database stores each account's dictionary. Without it there is no way to close the API or teach it your own terminology.
How do I authenticate requests to a self-hosted LanguageTool server?
Send username and apiKey as form parameters alongside text and language, using the values in LT_API_USERNAME and LT_API_KEY. To add another caller, insert a row into the users table with a different key.
Can I use the confused-word rules that need n-gram data?
Not by default: that data set is about 8.9 GB for English alone. Attach a large volume, unpack the data into it and point langtool_languageModel at the mount path.
How do I connect the LanguageTool browser extension to my own server?
Set the add-on's server URL to your deployment's domain. The add-on sends no API key, so switch langtool_anonymousAccessAllowed to true first — which makes the endpoint usable by anyone with the URL, so treat it as a deliberate choice.
Template Content
