lexaudit
Finds odd, wrong or copied-from-another-language words in your texts, and tells you which pages to fix first.
In plain words
You write or translate articles, courses or documentation. A normal spellchecker shouts about every brand name, abbreviation and long German word, and still misses the words that really hurt: a word copied from another language ("calque"), a real word used with the wrong meaning ("false friend"), or a word someone invented.
lexaudit reads your files, ignores the harmless things, and gives you a short ranked list: "look at this page first." It runs on an ordinary laptop in about a second. No graphics card, no internet, no account.
It only reports. It never changes your texts.
Unknown terms? See the glossary.
- Languages: English (
en), German (de), Spanish (es), Polish (pl), Russian (ru), Swedish (sv), Ukrainian (uk) - Hardware: CPU only
- Author: Vadim Nareyko (github.com/nareyko)
- License: AGPL-3.0-or-later
Try it in 60 seconds
1. Install and get the dictionaries
uv sync
uv run lexaudit fetch-dicts # downloads 7 spelling dictionaries, no admin rights
uv run lexaudit doctor # shows what is ready and what is missing
fetch-dicts saves dictionaries in your user cache folder. doctor confirms that no GPU is needed and lists the installed languages. If the system hunspell program is installed, lexaudit uses it because it is a little faster. If not, a built-in Python checker is used, so nothing else has to be installed.
2. Check a file or a whole project
# One file or folder, no settings file needed
uv run lexaudit audit --path ./README.md --locale en
# Or create starter settings first, then check everything
uv run lexaudit init
uv run lexaudit audit --locale en
3. Open the report
The reports are in the output folder, one subfolder per language. Start with queue.md:
| score | unique_suspects | path | top_words |
|---|---|---|---|
| 12.0 | 2 | docs/en/en-04-defect-known-calques.md | orientir surveyness |
| 6.0 | 1 | docs/en/en-05-defect-false-friend.md | denseness |
| 1.6 | 2 | docs/en/en-03-clean-unseen-jargon.md | vinylester haulout |
A higher score means "look here first". top_words shows the words behind the score.
4. Ask why a word was flagged
uv run lexaudit explain orientir --locale en
word: orientir (normalized: orientir, locale: en)
status: calque (tier: confirmed)
reason: loan-calque-orientir | detectors: calque, hunspell
editorial hint: working rule / ballpark / figures - not orientir
5. Reproduce our test results
uv run lexaudit audit --config examples/synthetic-demo/lexaudit.config.yaml
Then open tmp/synthetic-demo-out/<language>/queue.md.
How good is it? An honest answer
We built a 42-page test set in all 7 languages: 21 clean technical pages and 21 pages with planted problems. Some problems are known to the rules, some are brand new words the rules have never seen. Details: docs/synthetic-benchmark.md.
| Setup | Bad page in top 2 | Bad page in top 3 | MAP (0 to 1, higher is better) | Known problems found | Brand new problems found | Time |
|---|---|---|---|---|---|---|
| A. Plain spellchecker | 0.0% | 23.8% | 0.389 | 0 of 26 | 0 of 33 | 0.54 s |
| B. Plus your word lists | 7.1% | 23.8% | 0.421 | 0 of 26 | 0 of 33 | 0.62 s |
| C. Full lexaudit | 100.0% | 66.7% | 0.838 | 26 of 26 | 26 of 33 | 0.66 s |
What this means:
- Pages with known problems come first in every language. The plain spellchecker puts clean pages first.
- About 78% of all planted problems are found, including words the rules never saw. About 22% are missed.
- Weak spot: a clean page with a repeated new technical term can outrank a page with a single new invented word. Adding the term to your word list, or using the optional
labelstep, fixes this.
Documentation
Start with docs/README.md.
| Guide | What you learn |
|---|---|
| Glossary | Every term in plain words |
| Benchmark | The 42-page test, step by step |
| Architecture | What goes in, what comes out |
| Pipeline | The gates every word passes |
| CLI reference | All commands |
| Agent workflow | From report to fixed page |
| Scores and metrics | How pages are scored |
More commands
# Re-rank pages, filter by source (docs, academy, model_pack)
uv run lexaudit rank --locale ru --mode weighted --sources=docs
# Add every page that contains a known bad word to your to-do list
uv run lexaudit expand-needle --needle orientir --locale all \
--write-queue /abs/path/to/rewrite-queue.md
# Optional: ask a language model for a second opinion (your own endpoint)
uv run lexaudit label --locale ru --top-pages 20 --top-words 50 --tiers likely,weak --profile cpu
# Compare two runs
uv run lexaudit diff --baseline .../report.json --current .../report.json --out /tmp/diff.json
For contributors
Setup and checks:
uv sync --extra dev
uv run ruff check . && uv run ruff format --check .
uv run mypy --strict src/
uv run pytest
uv run python scripts/crap_report.py
uv run mutmut run && uv run python scripts/check_mutation_score.py --min-percent 80
uv build
Test layers: unit and integration tests (branch coverage 80% or more), the 7-language benchmark, property-based fuzzing (Hypothesis), golden regression with a read-only check of your files, JSON Schema contract, complexity gate (CRAP), mutation testing (kill rate 80% or more).
Pictures in docs/images are generated from code: run python scripts/render_diagrams.py (needs Inkscape and Pillow). Never edit the JPG files by hand.
Origin and author
Created and maintained by Vadim Nareyko (github.com/nareyko). It grew out of auditing multilingual courses and encyclopedias at FairHelm.
Metadata
Release files for lexaudit 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| lexaudit-0.1.0.tar.gz | 1.3 MB | Without provenance | Details for lexaudit-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| lexaudit-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for lexaudit-0.1.0-py3-none-any.whl |
Total release size: 1.4 MB
Release files / lexaudit-0.1.0.tar.gz
| Download URL | lexaudit-0.1.0.tar.gz |
|---|---|
| Size | 1.3 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d2fec7bd66a5d31e4d54d253ee604e57e0ed7752473eeba538870a37dea30968
|
|
BLAKE2b-256 checksum How to use checksums |
916c84f2921840138f91df0324f11403d01b2d877b302c5de67dad4556dfb014
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / lexaudit-0.1.0-py3-none-any.whl
| Download URL | lexaudit-0.1.0-py3-none-any.whl |
|---|---|
| Size | 77.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1ce0ffff951f1e510d9ab81bfb5092bab3803b6d319a6d34458e6e4cfbda721f
|
|
BLAKE2b-256 checksum How to use checksums |
bca43af0fab16744638206e05543192d6258dc6afccbb2b28bdaac2a61cc7645
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for lexaudit 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.