Engineering can sometimes help in places that seem far removed from my own field.

That thought led me to create textlint-rule-ja-grade-kanji , a textlint rule that flags kanji not yet taught by a specified elementary school grade.

It started with a post on X about proofreading self-published books . The post pointed out that if a passage is supposed to have been written by an elementary school student, limiting it to kanji taught by that grade can help make the character feel authentic.

What caught my attention was not merely a way to portray a particular character. Honestly, the character was beside the point.
Could textlint bring an engineer’s perspective to proofreading novels and collaborative anthologies, and in doing so support cultures such as self-publishing?

That curiosity made me start building.

Writing and Proofreading Are Different Jobs

I believe that turning what is in your head into prose and proofreading that prose are different jobs.

This is not about dividing people into humanities and science backgrounds. A writer may be able to express rich ideas in words without being able to catch every inconsistency in notation or every deviation from a rule.

Some proofreading decisions require reading the context and considering the intent behind an expression.
Others can be reduced to explicit rules.

Engineers can build systems to assist with the latter.

I chose grade-level kanji as my first subject. A textlint rule for checking Joyo kanji, the kanji designated for common use, already existed. A rule for grade-level kanji had also been created several years earlier, but when I began development, it appeared to be no longer maintained.

That does not mean I thoroughly investigated every existing rule before deciding to build a new one. My curiosity to try making one myself came first, and I only learned about the similar package in detail after I had finished mine.

Checking One Rule Only

Based on the Ministry of Education, Culture, Sports, Science and Technology’s official grade-by-grade kanji allocation table, textlint-rule-ja-grade-kanji checks whether a text uses only kanji taught by the specified grade.

For example, with the rule configured for second grade, the phrase “植物を観察する” reports three characters individually: “植,” taught in third grade, and “観” and “察,” taught in fourth grade.

The first use case that came to mind was dialogue or writing by an elementary school character, as in the post that inspired the project.
The rule can also help people creating educational materials or notices for elementary school students find kanji that readers in the target grade may not yet be able to read.

From the outset, I knew the rule needed settings for the target grade, exceptions for kanji used in proper nouns, and sections excluded from checking.
During implementation, AI also pointed out the need to detect kanji absent from the official table and to handle incorrect character positions when uncommon kanji appear.

Unicode divides the range of numbers assigned to characters into units called planes . The first plane contains many commonly used characters, while the planes beyond it are called supplementary planes. For example, “吉” is in the first plane, but the visually similar “𠮷” is a kanji in a supplementary plane.

JavaScript internally treats most characters in the first plane as one unit, while it treats characters in supplementary planes as two units. Both look like a single character, so if every kanji were counted as one unit, the reported position of “𠮷” itself and of the characters following it would be incorrect.

I therefore added processing that identifies kanji by Unicode code point while calculating the positions passed to textlint according to JavaScript’s counting method. After confirming why that processing was necessary, I incorporated it along with detection of kanji absent from the grade-by-grade allocation table.

The rule could support more cases if it also checked vocabulary and ruby annotations.

However, adding too many rules to a single package would also add more use-case-specific exceptions, increasing configuration and maintenance costs. For now, I have kept the package focused on grade-level kanji, a rule with a clear authoritative basis.

Using Primary Sources and AI as Separate Pairs of Eyes

I expected to find the kanji data for each grade in the Ministry of Education’s Courses of Study for Elementary Schools . My work sometimes requires researching the Ministry’s website, so I knew how to trace the information back to a primary source.

In practice, I searched the Courses of Study for the grade-by-grade kanji allocation table myself while having AI independently look for the same information in the background. Rather than asking AI to verify information I had already found, I compared the results of two separate searches.

I delegated most of the implementation and test code to AI.
But I did not treat passing tests alone as proof of correctness. I checked what each test covered and whether its expected result matched the primary source.

AI is strong at implementing quickly and suggesting edge cases that are easy to miss.
I remained responsible for deciding which suggestions to accept, whether the tests actually verified the specification, and whether the source data was trustworthy. This division of work let me avoid handing everything over to AI without limiting the project to manual work alone.

Documentation for Writers Who Do Not Know textlint

The intended users are not only people who program regularly. They also include people who write in Word or a text editor and may feel lost when they see lines of English words in a terminal.

Alongside the README, I therefore wrote a setup guide titled “Your First Kanji Check” . It starts with installing Node.js, and every command is presented in a form that readers can copy and run.

The guide also explains in advance that Word files cannot be checked directly, how to troubleshoot a missing configuration file, and how to address common errors.

I avoided technical terms where possible, but I did not hide the rule’s limitations.

The rule can process plain text and Markdown files. A Word manuscript must first be copied into a plain-text file. Moreover, it detects kanji not yet taught at the target grade; it does not assess the overall difficulty or readability of a passage.

The rule is only a detector. The writer decides whether to replace a reported kanji with hiragana or retain it for a reason such as its use in a proper noun. Rather than making compliance with the rule an end in itself, I limited the machine’s job to returning the information needed for that decision.

What I Learned by Publishing on npm

I published the finished rule as an npm package .

Publishing it to npm was not especially difficult. It had simply been long enough that I had forgotten how to log in and needed to look up the procedure again.

After publication, the package received a few downloads. Download numbers were not a success metric for me. Even so, I was glad to see evidence that someone I did not know had tried something I made out of curiosity.

This project began by combining an engineering perspective with a post about proofreading self-published books. But the people and cultures engineering can support need not be limited to self-publishing.

Experiences in games can offer insights into team management, just as static analysis can be brought into cultures built around writing.

The materials available to me are the ideas, culture, and technology I have acquired as an engineer.
Other people have different materials drawn from their own experiences.

Even when something seems far removed from your own specialty, combining it with the materials you already have may reveal a small, rule-based problem you can solve.

Build a small version of the idea and publish it.

It may lead to a technical discovery, or it may create a connection with people and cultures you had never encountered before.
For me, it was an enjoyable experience.