Spell checker system in Flutter

Implement a simple spell checker system in Flutter

Daniel Dang
4 min readSep 11, 2022

A spell checker is important since your app has an editable text form. And you don’t want to rely on yourself when typing to believe that there are no mistakes. Then, having a spell checker can help you a lot with misspelled words.

The spell checker system is mostly supported by engines for the web, apps,… For example, like in the web with HTML, we have enumerated attribute spellcheck for editable tags. With iOS or Android native, they also have spellCheckingType or Spell checker framework. But not in Flutter, they’re setting spell checkers as a to-do for both web and app.

Then, in this article, I’ll show you how to do a simple spell checker system that can work well for your app if you don’t want to wait for the Flutter team.

As you can see the result here:

Spell checker system demo

I’ll skip the part about initializing the new app in Flutter and go straight to the main point.

I’ll divide it into 2 parts:

1. How to create a red wiggle underline for a specific word in an editable text widget.

If you look over the document for TextStyle you can see there’s a section where they mentioned creating a wavy red underline for black text. In this way, you can set the text style for each by converting to TextSpan.

Here we go, we need to extend a custom TextEdittingController, I’ll call it CustomTextEdittingController, and give it a property listErrorTexts to store all the words that need a red underline on it.

Now, you need to override the buildTextSpan method by checking listErrorTexts. If your text match any in listErrorTexts then give it a custom style. I used splitMapJoin powered by Dart language to map them into multiple TextSpans.

Customize a TextEdittingController

Remember to put them in try-catch in case It fails to find the match one.

2. Now it’s time to implement the spell-checking algorithm

I call it algorithm sounds a bit mysterious but here we just simply write a function to check for every typed word.

The idea is simple, every time you type the word and hit the space, then you check for the word right before it. If it is misspelled then add it to listErrorTexts, otherwise you’ll still need to save it in a cached array so when this word appears again you don’t need to lookup in the dictionary anymore.

For the dictionary, you can use this package list_english_words but for me, that package has too many words (~380k words) and many are redundant for the usual English language. So I got my own list which is just about ~84k words. (You can find it at the end of this article).

I created a TextFormField widget in a separate file and a function called handleSpellCheck assigning to the onChange event of TextFormField.

  • ignoreLastWord param: It’s used to ignore the last word which is the one that you are typing. This word is only checked when you hit the space. This param is useful in case you paste a paragraph from somewhere else and you want it to check the last word also.
  • _isWordHasNumberOrBracket function: We won’t check for words that contains number or bracket (Ex: 38timf, ew()) because it might cause your regex in TextEdittingController fail to execute. But if you still want to check, you can improve it on your own.
  • wordToCheckInLowercase & wordToCheck: I created 2 variables, one in lowercase to lookup in the dictionary and the other to send to our controller and make sure that it highlights the right word.

Alright, now your spellchecker can work well as expected but you might wonder how to check the last word if we don’t hit any space at the end.

Then, you need to wrap your TextFormField in a Focus widget to detect whether the user’s mouse has lost focus.

You also need to call this function in initState when you paste a paragraph from somewhere else. One more, It's more convenient if you implement a custom TextFormField and can re-use it anywhere. Then you need to assign the default value to your CustomTextEdittingController in initState().

Final thoughts

Above is the very simple way to create a spell checker system. The algorithm is basic and might not be the best approach. I did try to measure the execution time and it only takes approximately 50~ ms to finish the task.

If you have any better approaches or solutions for the algorithm, feel free to point them out, I’d appreciate that. By the way, you can refer to the full source code and also the list of English words here.

--

--

Daniel Dang

A Vietnamese left-handed guy who finds himself falling in love with many things.