Textstat-rs
Rust port of the textstat textual analysis library, with Python bindings. Drop-in replacements for 11 key metrics in British and US English.
99.98% exact output match, with at least 2.4x-7x speedup, with 2 most sped-up metrics at ~14x and ~79x based on benchmarking scripts included in repo, running on Wikipedia dataset as a varied, modern text corpus.
Installation
pip install textstat-rs
Pre-release versions need pip install --pre textstat-rs.
Requires Python 3.10+. Wheels are built for Linux (x86_64, x86, aarch64, armv7; glibc and musl), macOS (x86_64, arm64) and Windows (x64, arm64). They are abi3 wheels, so one wheel per platform covers every supported Python version. On other platforms pip falls back to the sdist, which needs a Rust toolchain to build.
Usage
Import name is textstat_rs; every metric takes the text as its first argument.
import textstat_rs
text = "The cat sat on the mat. It was a sunny day."
textstat_rs.flesch_reading_ease(text) # 108.96159090909092
textstat_rs.flesch_kincaid_grade(text) # -0.5722727272727273
textstat_rs.text_standard(text) # '0th and 1st grade'
The exposed metrics match textstat's signatures, so an existing import can be swapped in place:
import textstat_rs as textstat
Optional arguments are the same as the Python library, other than the exceptions noted below:
textstat_rs.gunning_fog(text, syllable_threshold=3)
textstat_rs.linsear_write_formula(text, strict_lower=False, strict_upper=True)
textstat_rs.reading_time(text, ms_per_char=14.69)
The counting helpers the formulas are built on are exposed too: syllable_count, sentence_count, lexicon_count, char_count, letter_count, polysyllabcount, miniword_count and difficult_words.
Language
British and American English are both supported. The default is en_US, matching textstat.
Set it once, the way textstat does:
textstat_rs.set_lang("en_GB")
textstat_rs.get_lang() # 'en_GB'
textstat_rs.syllable_count("colourful") # 3 (2 under en_US)
supported_langs() returns canonical tags, to allow enumerating locales rather than hardcoding them:
textstat_rs.supported_langs() # ['en_US', 'en_GB']
You can also set the locale per call. It is keyword-only, and overrides over the default:
textstat_rs.flesch_reading_ease(text, lang="en_GB")
lang= is offered only where the locale can change the answer. It reaches exactly one decision — which hyphenation dictionary spells out syllables for words missing from CMUdict — so char_count, lexicon_count, sentence_count, letter_count, miniword_count, reading_time, mcalpine_eflaw, coleman_liau_index and automated_readability_index do not take it, because it would do nothing.
Tags are resolved the way pyphen does — lowercased, - normalised to _, then trailing subtags dropped until something matches — so en-GB, EN_GB and en_US_posix all work.
Four differences from textstat worth knowing:
- Only English is supported.
textstatwould accept"fr"and reach for French coefficients and a French dictionary. textstat-rs vendors only the two English hyphenation dictionaries, so anything that doesn't resolve toen_USoren_GBraisesValueError. - Bad locales fail immediately.
textstat'sset_langis a bare assignment, so a typo is accepted and only surfaces later as aKeyErrorfrom insidepyphen— and only once some word actually misses CMUdict, which for a short text may be never. - Bare
"en"means British.pyphenregisters a short name for the first matching file in sorted order, andhyph_en_GB.dicsorts beforehyph_en_US.dic. Kept deliberately, soenanden_AUget the British dictionary. The default when nothing is set is stillen_US. lang=is honoured.textstatstill acceptssyllable_count(text, lang=...)but warns and discards it. Here it works.
Python Comparison
Functions
Exposed Metrics
| Python function | Exposed? | Notes |
|---|---|---|
flesch_reading_ease |
✅ | |
flesch_kincaid_grade |
✅ | |
smog_index |
✅ | |
coleman_liau_index |
✅ | |
automated_readability_index |
✅ | |
dale_chall_readability_score |
✅ | |
linsear_write_formula |
✅ | signature parity (strict_lower, strict_upper) |
gunning_fog |
✅ | Rust exposes syllable_threshold arg, Python hardcodes it |
spache_readability |
✅ | Rust missing float_output arg |
text_standard |
✅ | Rust missing float_output arg, returns String only |
reading_time |
✅ | |
mcalpine_eflaw |
✅ | |
dale_chall_readability_score_v2 |
❌ | |
lix |
❌ | |
rix |
❌ | |
fernandez_huerta |
❌ | Spanish |
szigriszt_pazos |
❌ | Spanish |
gutierrez_polini |
❌ | Spanish |
crawford |
❌ | Spanish |
gulpease_index |
❌ | Italian |
wiener_sachtextformel |
❌ | German |
osman |
❌ | Arabic |
Parity
Scores are compared against textstat over 1000 Wikipedia articles (up to 5000 chars each), across en_US and en_GB: 99.98% of 22000 comparisons match exactly, and the largest disagreement anywhere is 0.049566.
| locale | comparisons | exact match | max delta |
|---|---|---|---|
| en_US | 11000 | 99.98% | 0.049566 |
| en_GB | 11000 | 99.97% | 0.049566 |
Metrics returning a grade band rather than a number are compared as exact strings: text_standard matches exactly 1000/1000 in en_US, 1000/1000 in en_GB.
Per metric (en_US)
| metric | avg delta | max delta |
|---|---|---|
| flesch_reading_ease | 0.000000 | 0.000000 |
| flesch_kincaid_grade | 0.000000 | 0.000000 |
| automated_readability_index | 0.000000 | 0.000000 |
| coleman_liau_index | 0.000000 | 0.000000 |
| dale_chall_readability_score | 0.000000 | 0.000000 |
| gunning_fog | 0.000050 | 0.049566 |
| smog_index | 0.000000 | 0.000000 |
| linsear_write_formula | 0.000000 | 0.000000 |
| mcalpine_eflaw | 0.000000 | 0.000000 |
| spache_readability | 0.000011 | 0.010657 |
| reading_time | 0.000000 | 0.000000 |
Generated from dc1a373 on 2026-08-24, python 3.12.4 vs textstat 0.7.13.
Performance
One call per metric over 100 concatenated Wikipedia articles (0.46 MB), median of 5. Both libraries are warmed first, so these are steady-state numbers with lazy resource loading excluded.
| metric | textstat-rs (ms) | textstat (ms) | speedup |
|---|---|---|---|
| flesch_reading_ease | 39.29 | 149.60 | 3.81x |
| flesch_kincaid_grade | 36.45 | 148.43 | 4.07x |
| automated_readability_index | 18.87 | 51.10 | 2.71x |
| coleman_liau_index | 13.68 | 59.91 | 4.38x |
| dale_chall_readability_score | 28.11 | 186.25 | 6.63x |
| gunning_fog | 28.72 | 187.38 | 6.52x |
| smog_index | 27.78 | 207.86 | 7.48x |
| linsear_write_formula | 0.04 | 4.16 | 107.98x |
| mcalpine_eflaw | 18.61 | 42.15 | 2.26x |
| spache_readability | 27.91 | 193.68 | 6.94x |
| reading_time | 0.79 | 12.80 | 16.27x |
On top of that, the first call in a fresh process pays a one-off load of the syllable and word-list resources: up to 34 ms for textstat-rs against 361 ms for textstat.
Generated from dc1a373 on 2026-08-24, python 3.12.4 vs textstat 0.7.13.
Third-party data
The scoring resources are compiled into the extension by include_str!, so
they ship inside every wheel. Their notices ship with them, under
textstat_rs-<version>.dist-info/licenses/.
| Data | Source | Licence | Notice |
|---|---|---|---|
cmudict.txt |
CMU Pronouncing Dictionary | BSD-2-Clause-style | src/data/cmudict-LICENSE.txt |
hyph_en_US.dic |
pyphen / LibreOffice, from hyphen.tex |
BSD-style | src/data/README_hyph_en_US.txt |
hyph_en_GB.dic |
pyphen / LibreOffice, from ukhyphen.tex |
BSD-style | src/data/README_hyph_en_GB.txt |
easy_words.txt |
textstat (Dale-Chall list) | MIT | covered by textstat's MIT licence |
Both .dic files are vendored byte-for-byte from pyphen, and the notice files
keep their upstream names so they can be diffed against it directly. The
pyphen-LICENSE.txt note covers pyphen itself (GPL 2.0+/LGPL 2.1+/MPL 1.1
tri-licence). None of pyphen's code is used here, only the two dictionaries,
which carry the BSD-style terms above.
Only the data is third-party. The Rust and Python code in this repository is MIT, per LICENSE.
Metadata
Release files for textstat-rs 2.0.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 | |
|---|---|---|---|
| textstat_rs-2.0.0.tar.gz | 1.2 MB | Details |
Built distributions (wheels)
Total release size: 21.1 MB
Release files / textstat_rs-2.0.0.tar.gz
| Download URL | textstat_rs-2.0.0.tar.gz |
|---|---|
| Size | 1.2 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c035e7bf70971abd106d945932df98528e67736a77cd85975d7cba026216dc34
|
|
BLAKE2b-256 checksum How to use checksums |
f3e1337f0381918403132e0c2a7de4ba3e5eef2112c53d6b83326b667bc4b7a9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 24, 2026.
Transparency logRelease files / textstat_rs-2.0.0-cp310-abi3-win_arm64.whl
| Download URL | textstat_rs-2.0.0-cp310-abi3-win_arm64.whl |
|---|---|
| Size | 1.9 MB |
| Tags | CPython 3.10 Windows ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
744d4aaaae1dfc8ecb7a97c9ac7ba0410a9abeae0e4ca4c96fbe73a6d36b0e6d
|
|
BLAKE2b-256 checksum How to use checksums |
58f10c0728adcdf054e8be0bab2c3e9f638052723bd3661e1009f5ecbba81f78
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 24, 2026.
Transparency logRelease files / textstat_rs-2.0.0-cp310-abi3-win_amd64.whl
| Download URL | textstat_rs-2.0.0-cp310-abi3-win_amd64.whl |
|---|---|
| Size | 1.9 MB |
| Tags | CPython 3.10 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
37b17fbe2aa459e52846a7203d7a75cd5dd5d8c40b23d543f19ce6d007827c27
|
|
BLAKE2b-256 checksum How to use checksums |
28d7e8a030dbfcfe2f00d7e34cdba4e000a3749d92d93f237293b409f66db5de
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 24, 2026.
Transparency logRelease files / textstat_rs-2.0.0-cp310-abi3-musllinux_1_2_x86_64.whl
| Download URL | textstat_rs-2.0.0-cp310-abi3-musllinux_1_2_x86_64.whl |
|---|---|
| Size | 2.2 MB |
| Tags | CPython 3.10 Linux musl 1.2+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
11b05909c91f1ef53ba6fea39705402e9f954e062d40b5423ded33dcc384b4fe
|
|
BLAKE2b-256 checksum How to use checksums |
5e6da65f54771f4342b2ac41b142b7ba6ad49c9c1d319c03068a87673ee803dd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 24, 2026.
Transparency logRelease files / textstat_rs-2.0.0-cp310-abi3-musllinux_1_2_aarch64.whl
| Download URL | textstat_rs-2.0.0-cp310-abi3-musllinux_1_2_aarch64.whl |
|---|---|
| Size | 2.1 MB |
| Tags | CPython 3.10 Linux musl 1.2+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
0ef1b55c9453e7a9d1965cc387106b3d3032203ee98436e4427563ac5458cf01
|
|
BLAKE2b-256 checksum How to use checksums |
169f2bef5059e1120c8c54d179fb65599c2da064bd3a4c5c987837fe27d0da45
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 24, 2026.
Transparency logRelease files / textstat_rs-2.0.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | textstat_rs-2.0.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 2.0 MB |
| Tags | CPython 3.10 Linux glibc 2.17+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
349e9b5e1887cd08edb5010744a1f263ee46dde9f05837944645f0ec48ebd463
|
|
BLAKE2b-256 checksum How to use checksums |
04c1b7627e4b93b8e745c40602c53340101df2091740be7468ec75d3c73560c4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 24, 2026.
Transparency logRelease files / textstat_rs-2.0.0-cp310-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
| Download URL | textstat_rs-2.0.0-cp310-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl |
|---|---|
| Size | 1.9 MB |
| Tags | CPython 3.10 Linux glibc 2.17+ ARMv7l abi3 |
|
SHA-256 checksum How to use checksums |
ba2d55892fed99f1b0a289fd6c2d55106c05cfb45bf8f2f11fc06b7ffae054a5
|
|
BLAKE2b-256 checksum How to use checksums |
671879244bdc6bf059c32523f029329191e177ae58437892f304cb6f4604c9b7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 24, 2026.
Transparency logRelease files / textstat_rs-2.0.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| Download URL | textstat_rs-2.0.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
|---|---|
| Size | 1.9 MB |
| Tags | CPython 3.10 Linux glibc 2.17+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
a6b9cb2720439eb35cae98340dcca683f5edaa5a42bf1bb72e6dee9f73d62f74
|
|
BLAKE2b-256 checksum How to use checksums |
c67769dd349edce634352fcafb114c6a06fd07ac5acdb02959724136ad100381
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 24, 2026.
Transparency logRelease files / textstat_rs-2.0.0-cp310-abi3-manylinux_2_5_i686.manylinux1_i686.whl
| Download URL | textstat_rs-2.0.0-cp310-abi3-manylinux_2_5_i686.manylinux1_i686.whl |
|---|---|
| Size | 2.0 MB |
| Tags | CPython 3.10 Linux glibc 2.5+ x86-32 abi3 |
|
SHA-256 checksum How to use checksums |
72b986614551e848e27629cdbfdaaa0df1456a65fd8937d74533e494b2e551e2
|
|
BLAKE2b-256 checksum How to use checksums |
5085586c80b00d9bb916f14eca81c74d104908aac984de3c514fc9fe7e043097
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 24, 2026.
Transparency logRelease files / textstat_rs-2.0.0-cp310-abi3-macosx_11_0_arm64.whl
| Download URL | textstat_rs-2.0.0-cp310-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 1.9 MB |
| Tags | CPython 3.10 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
8d2adda9c54debf840b493271cdbc0699ce20779974d8833f3800c94b22d0406
|
|
BLAKE2b-256 checksum How to use checksums |
71ac2783c4b51bb493acd9e12dd6bb2630760dba801956a231f672c083bf86ef
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 24, 2026.
Transparency logRelease files / textstat_rs-2.0.0-cp310-abi3-macosx_10_12_x86_64.whl
| Download URL | textstat_rs-2.0.0-cp310-abi3-macosx_10_12_x86_64.whl |
|---|---|
| Size | 2.0 MB |
| Tags | CPython 3.10 abi3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
bdf99a58f253233dd830c0ae01532f0d80ce6d13d95975cb9fc5af13aadfb22d
|
|
BLAKE2b-256 checksum How to use checksums |
150b1af1a99f4a1cd2db0a3c223c59ce3b5a5fc391e8318103151bda7d134474
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 24, 2026.
Transparency log