---
title: "Deploy Deploy LanguageTool for Obsidian"
description: "Grammar checks in Obsidian against your own LanguageTool"
category: "Other"
url: https://railway.com/deploy/deploy-languagetool-for-obsidian
---

# Deploy Deploy LanguageTool for Obsidian

Grammar checks in Obsidian against your own LanguageTool

**[Deploy Deploy LanguageTool for Obsidian on Railway](https://railway.com/template/deploy-languagetool-for-obsidian)**

Machine-readable deploy manifest (JSON, validated by TemplateCI): https://railway.com/deploy/deploy-languagetool-for-obsidian/manifest.json

- **Creator:** onepush
- **Category:** Other

## Template content

### LanguageTool

- **Image:** erikvl87/languagetool:6.8@sha256:ef8fa12cbd485166c9ceeb7139d76d56d07707a624da6bb1fc1fbb5411750527
- **Start command:** `/bin/bash -c 'cd /LanguageTool; N=/ngrams; U=https://languagetool.org/download/ngram-data; ROOT=0; [ "$(id -u)" = 0 ] && ROOT=1; [ $ROOT = 1 ] && [ -d $N ] && chown languagetool:languagetool $N; JOBS=""; for l in $(echo "${NGRAM_LANGUAGES:-none}" | tr "A-Z," "a-z "); do case $l in none|off|false) continue ;; en) f=ngrams-en-20150817.zip ;; de) f=ngrams-de-20150819.zip ;; es) f=ngrams-es-20150915.zip ;; fr) f=ngrams-fr-20150913.zip ;; nl) f=ngrams-nl-20181229.zip ;; *) echo "ngrams: unknown language $l (choose from en,de,es,fr,nl)" >&2; continue ;; esac; if [ -d $N/$l ]; then echo "ngrams: $l already on the volume"; elif [ -d $N ] && [ -w $N ]; then JOBS="$JOBS $l:$f"; else echo "ngrams: $l requested but $N is not a writable volume; add a volume at $N (see README)" >&2; fi; done; if [ -n "$JOBS" ]; then P=$$; ( NEW=0; for j in $JOBS; do l=${j%%:*}; f=${j#*:}; echo "ngrams: downloading $f in the background (LanguageTool keeps serving meanwhile)"; rm -rf $N/.$l.zip $N/.$l.tmp; if curl -fsSL --retry 5 -o $N/.$l.zip $U/$f && unzip -q -o $N/.$l.zip -d $N/.$l.tmp && [ -d $N/.$l.tmp/$l ]; then mv $N/.$l.tmp/$l $N/$l; rm -rf $N/.$l.zip $N/.$l.tmp; [ $ROOT = 1 ] && chown -R languagetool:languagetool $N/$l; echo "ngrams: $l installed"; NEW=1; else echo "ngrams: $l download or unzip failed (check free space on the volume)" >&2; rm -rf $N/.$l.zip $N/.$l.tmp; fi; done; if [ $NEW = 1 ]; then echo "ngrams: restarting so LanguageTool loads the new data"; kill $P; fi; ) & fi; if [ -z "$langtool_languageModel" ]; then for l in en de es fr nl; do [ -d $N/$l ] && export langtool_languageModel=$N && break; done; fi; [ -n "$langtool_languageModel" ] && echo "ngrams: languageModel=$langtool_languageModel"; if [ $ROOT = 1 ]; then exec su languagetool -s /bin/sh -c "echo \"running LanguageTool as \$(id -un)\"; exec bash start.sh"; fi; exec bash start.sh'`
- **Health check:** /v2/languages
- **Public domain:** Yes

## Documentation

# Deploy and Host self hosted LanguageTool Obsidian (Self-Hosted Grammar Checking for Obsidian) on Railway

This template runs a private LanguageTool server on Railway that the LanguageTool Integration plugin in Obsidian can call through a custom URL. Journal writers and researchers will find it useful.

## About Hosting LanguageTool Obsidian open-source software on Railway (self hosted LanguageTool Obsidian plugin on a self-hosted server template)

This template runs one LanguageTool service built on the erikvl87/languagetool 6.8 image, listening on port 8010 with a health check at GET /v2/languages.

## Why Deploy LanguageTool Obsidian, the Grammarly alternative on Railway (Railway Free Trial)

Grammarly sends every note to its cloud, and the bill grows per seat. You pay one flat hosting fee for a single Java service. Railway's $5 trial is enough to test the setup before you commit.

Railway is a singular platform to deploy your infrastructure stack. Railway will host your infrastructure so you don't have to deal with configuration, while allowing you to vertically and horizontally scale it.

By deploying LanguageTool Obsidian on Railway, you are one step closer to supporting a complete full-stack application with minimal burden. Host your servers, databases, AI agents, and more on Railway.

### Railway vs Other Hosting Providers and VPS for LanguageTool Obsidian self hosting

Railway runs the container and public domain for you, so you only tune the Java heap. Here is how that compares with a VPS you manage.

| Provider | What You Get with Railway | What You Get with the Other Provider |
| --- | --- | --- |
| DigitalOcean | A template with the image pinned, a public domain on port 8010, and automatic restarts. | A Droplet you size and patch, with full root access. |
| AWS | Environment variables set in the dashboard and no VPC to configure. | Fine grained networking, but you build the runtime and TLS yourself. |
| Hetzner | A running service in minutes with usage billing and no server to harden. | Cheap dedicated RAM for big heaps, but you install Docker and keep it updated. |

Pick the option that matches how much of the server you want to own.

## Common Use Cases for hosted LanguageTool Obsidian

- **Proofreading long notes:** Check journal and research notes against your own server without uploading the vault to a cloud service. The plugin sends only the text being checked, not your whole vault.
- **Checking multilingual notes:** Pin each note's language with lt-language in its frontmatter, for example lt-language: de-DE. Notes without the key use Auto Detect.
- **Excluding drafts or sensitive pages:** Tag a note with lt-ignore and every check skips it. Set lt-autocheck: false to keep a note to manual checks only.
- **Tuning strictness:** Turn on Picky Mode for the stricter rule set, then list noisy rule IDs under Disable Specific Rules.
- **Sharing one grammar server:** Point several devices or a docs pipeline at the same /v2/check endpoint, so one server covers your laptop, your phone, and your build.

## Dependencies for LanguageTool Obsidian Docker hosted on Railway

This section covers what you need before the template runs and how the single LanguageTool service is wired. Nothing here needs a secret.

### Deployment Dependencies for Managed LanguageTool Obsidian Service (Grammar Checker)

You need a Railway account (the $5 trial is enough to test). There is no volume by default; the optional /ngrams mount is only for n-gram data.

### Implementation Details for LanguageTool Obsidian (Using LanguageTool official docker image)

The start command runs as root only to own /ngrams, then drops to the languagetool user and execs the image's start.sh.

## How does LanguageTool Obsidian compare against other ways to run private grammar checks in Obsidian

### LanguageTool Obsidian vs Grammarly (Grammarly Alternative)

- **Where it wins for us:** Your text goes to a server you run, so note bodies never sit on a cloud writing assistant's infrastructure.
- **Cost shape:** You pay Railway for one service instead of a per-seat subscription.
- **Where Grammarly wins:** It has a polished browser and desktop experience and is quicker to start with, since our setup needs a deploy and a settings change in Obsidian.

### LanguageTool Obsidian vs Harper (Harper Alternative)

- **Engine:** Harper is a privacy-focused open-source checker that runs locally, which is hard to beat for pure offline use.
- **Where this stack wins:** LanguageTool is a mature Java server with a long rule history, and the same /v2/check endpoint can serve other clients too.
- **Resources:** LanguageTool carries a heavier Java footprint, so expect to tune the heap on a small Railway plan.

### LanguageTool Obsidian vs LanguageTool Premium (LanguageTool Premium Alternative)

- **Same engine:** Both run LanguageTool rules, so checking quality is close on the same language and settings.
- **Where Premium wins:** It offers a larger API allowance and a hosted endpoint, which suits heavy users who want nothing to run.
- **Privacy:** Self-hosting keeps text on your infrastructure, while the Premium endpoint sends it to LanguageTool's service.

### LanguageTool Obsidian vs ProWritingAid (ProWritingAid Alternative)

- **Focus:** ProWritingAid is a writing-analysis tool with grammar plus style and readability reports, which goes beyond a checker.
- **Where this stack wins:** It stays a focused grammar and style checker that sends only the text you check, not the whole vault.
- **Where ProWritingAid wins:** Its pacing and readability reports go deeper than LanguageTool does.

## How to use LanguageTool Obsidian (the OSS grammar and style checker)?

Here's the first-day sequence after a fresh deploy. The plugin side takes about five minutes once the server answers.

1. Deploy the LanguageTool Railway template and note its public domain (port 8010).
2. Check the server is up by opening GET /v2/languages on that domain.
3. In Obsidian, go to Settings, Community plugins, Browse and Install LanguageTool Integration, then enable it.
4. Set Endpoint to Custom URL and enter only the base URL, such as https://your-languagetool-domain, with no trailing path.
5. Optionally set Static Language to Auto Detect, or add lt-language: en-US to a note's frontmatter.
6. Turn on Picky Mode, or list rule IDs under Disable Specific Rules.
7. Test from a terminal before you trust the plugin:

```bash
curl -d "language=en-US" -d "text=a simple test" https://your-languagetool-domain/v2/check
```

A JSON body with a matches array means the server is healthy.

## How to self host LanguageTool Obsidian on other VPS Services (LanguageTool self hosting guide)

Run the same LanguageTool server on any VPS with Docker, then point the Obsidian plugin at it. Your note text stays on a machine you control.

### Clone the Repository

```bash
git clone https://github.com/onepush-dev/languagetool.git
cd languagetool
```

### Install Dependencies

You only need Docker on the host. The official image bundles Java and LanguageTool.

```bash
docker --version
```

### Configure Environment Variables

Set the port and Java heap, and leave the rest at defaults.

```bash
export PORT=8010
export Java_Xms=256m
export Java_Xmx=1g
```

### Start the LanguageTool Obsidian Application

Start the container and confirm it answers before you touch Obsidian.

```bash
docker run -d --name languagetool -p 8010:8010 erikvl87/languagetool:6.8
curl http://your-domain:8010/v2/languages
```

Railway handles the public domain, TLS, restarts, and health checks for you.

## Official Pricing of LanguageTool Obsidian (LanguageTool pricing)

LanguageTool Obsidian is free and open source, so there is no license fee for the server or the template. Railway offers a $5 trial to start.

## LanguageTool Obsidian cloud vs self hosted comparison (Pricing, features, costs, and more)

Self hosting LanguageTool keeps your notes on a server you control, but you trade a per-seat subscription for compute you pay for directly. Here is how the cost and hardware picture looks for this template.

### Monthly cost of self hosting LanguageTool Obsidian on Railway

Railway bills you for one Java service, which runs roughly $5-15 per month at light use with a 1 GB heap.

### System Requirements for Hosting LanguageTool Obsidian on a VPS

On a VPS, plan for enough RAM to cover the JVM heap plus OS overhead, since the default Java_Xmx of 1g is the main consumer. Raise the heap to 2g only if you run many languages or heavy concurrent checks.

## Frequently Asked Questions (FAQs)

### Do I need the public LanguageTool API, or can I keep my text on my own server?

You don't need the public API at all. Set the plugin's Endpoint to Custom URL, point it at your deployed Railway domain, and checks go to the server you run, so the text stays on your infrastructure.

### How do I stop a note from being checked?

Add the tag lt-ignore to the note and the plugin skips it across all checks. If you only want to turn off autocheck for one note, set lt-autocheck to false in its frontmatter instead.

### How do I set the language for a single note?

Add lt-language to the note's frontmatter, for example lt-language: de-DE. Leave it out and the plugin uses its default Auto Detect setting.

### What gets sent to the server when I check a note?

Only the text being checked gets sent, whether that's the whole document, the selection, or the changed lines during autocheck. The plugin never uploads your whole vault.

### Why is the autocheck delay limited to 50 ms on a custom URL?

The Custom URL endpoint has a 50 ms minimum because you control the server and its latency, so the plugin trusts you to set a shorter wait.

### What should I change if long documents time out?

Raise Java_Xmx to give the heap more room, and check that langtool_maxCheckTimeMillis isn't cutting checks short. Splitting very long notes into smaller pieces also helps.


## Similar templates

- [Rocky Linux](https://railway.com/deploy/rocky-linux) — Hosted Rocky Linux 9 workspace with SSH and persistent storage. 🚀
- [Foundry Virtual Tabletop](https://railway.com/deploy/X5tR6G) — A Self-Hosted & Modern Roleplaying Platform
- [Letta Code Remote](https://railway.com/deploy/letta-code-remote) — Run a Letta Code agent 24/7. No inbound ports, just deploy.

Open this page in a browser: https://railway.com/deploy/deploy-languagetool-for-obsidian
