
Tidy text: Sloppy notes that auto-correct, one line at a time
Sometimes I have ideas that I want to write down as fast as possible before I forget them. On mobile, slow typing, constant shift toggling, and switching keyboards for punctuation get in the way. What if I could type sloppily and the text could correct itself line by line? What if I could define my own rules for it? After all, text is the interface.
As a designer, I appreciate correct writing and typographic precision. I really care about the proper use of quotation marks, apostrophes, and dashes. But for notes, I sometimes just want to get my thoughts out without spending too much time on formatting. I’ll type fast, without correcting anything. It’s the digital version of bad handwriting that no one but the author can decipher.
What if I could type as fast as possible to capture my thoughts while still producing text that is correct and easy to read? That should be an easy task for today’s large language models, right?
I thought: “Let’s make a prototype with as little friction as possible. I’ll reach for Google Gemini 2.5 Flash Lite. I want a fast and inexpensive model for this simple task and don’t mess around with paying a subscription for an API.“ Of course: for a real app that I would use day-to-day, I wouldn’t like to send all my notes over to Google.
Balancing privacy and latency, I could have used WebLLM to run a model in-browser. Would it be fast enough for my use case? Fast enough on my machine? And what about other devices? What about the download size of the model? Gigabytes? Too many technical considerations and open questions that would have been a distraction from my original idea.
In the future, built-in AI models like Gemini Nano in browsers such as Chrome could handle this. There’s even a dedicated Proofreader API origin trial that mentions my use case: “Provide corrections during active note-taking.”
For now, though, let’s stick with the Gemini API for rapid prototyping.
Before diving into code, I first tested a system prompt in Google AI Studio:
System prompt:
> You’re a spell-checker. You’ll receive text that lacks proper capitalization. Return the text with correct capitalization. Primary languages: German, English.
After sending a few chat messages, I saw that this simple system prompt could quickly auto-correct my text. Next, I wanted to integrate it into a small web app that would perform corrections in a textarea, line by line.
Prototyping with Google Gemini and Cursor
This was my rough plan:
1. Go to Google AI Studio: https://aistudio.google.com
2. Get an API key
3. Choose model `models/gemini-2.5-flash-lite`
4. Write a system prompt
5. Create a small demo app with a textarea. On pressing enter, get the content of the current line.
6. Send the text to the API
7. Replace the content of the textarea with the API response
8. Handle focus, selection, and the text caret. After replacing the content, ensure the caret is on a new line.
Here’s the original example code from Google that shows how to make an API request with a system prompt and user message:
import { GoogleGenAI } from "@google/genai";
// The client gets the API key from the environment variable `GEMINI_API_KEY`.
const ai = new GoogleGenAI({});
async function main() {
const response = await ai.models.generateContent({
model: "gemini-2.5-flash",
contents: "Explain how AI works in a few words",
});
console.log(response.text);
}
main();
Looks straightforward.
Ideally, this would run on a Node.js server, but for my prototype, I started with a hard-coded key and later moved it to localStorage.
Changes I made to the example code:
- Provide the API key to the
GoogleGenAI
instance - Change the model to
gemini-2.5-flash-lite
- Use a more realistic test text
- Add a system prompt for capitalization
- Request structured output (JSON)
import { GoogleGenAI } from "@google/genai";
const ai = new GoogleGenAI({
apiKey: "**************************"
});
async function main() {
const response = await ai.models.generateContent({
model: "gemini-2.5-flash-lite",
contents: "wie wäre es ki zu nutzen um die gross kleinschreibung von einem text automatisch zu korrigieren wenn ich auf die nächste zeile springe?",
config: {
responseMimeType: "application/json",
systemInstruction: "You’re a spell-checker. You’ll receive text that lacks proper capitalization. Return the text with correct capitalization. Primary languages: German, English.",
},
});
console.log(response.text);
}
main();
We can run this in the browser, and it logs the result to the console.
I was surprised by the low latency—it almost feels local. Switching to gemini-2.5-flash
or gemini-2.5-pro
increases latency but slightly improves accuracy. For simple tasks like capitalization, a small fast model works perfectly.
Next, I integrated this into a UI that corrects text line by line. Using the idea above, I generated a demo component:
Prompt @claude-4.5-sonnet:
> write a component based on my idea. client-side api key and api call is fine.
+ context (everything from above)
Here’s a gist of the generated code.
Interestingly, Claude adjusted the system prompt:
Original prompt
> You’re a spell-checker. You’ll receive text that lacks proper capitalization. Return the text with correct capitalization. Primary languages: German, English.
Changed prompt
> You are a precise capitalization and punctuation fixer. You receive lowercase or inconsistently capitalized sentences in German or English. Return the same content with correct capitalization and punctuation, preserving meaning and formatting as much as possible. Do not add new content.
How the Demo Works
- Enter API key
- Type a line and press enter
- Wait for the corrected text
- Continue typing more lines
The prototype lacks styling, but the typing experience is interesting. It balances frictionless typing with occasional line-by-line corrections. Less distracting than instant corrections after every word. Perfect for a to-do list that can automatically parse, correct, and enhance new items.
I iterated further to prepend a dash for new lines, making it feel like a simple markdown-like list editor. Users can type new lines without a dash; after pressing enter, the previous line is corrected, and a dash is added. This gives clear feedback that the line was corrected.
Other features I added:
Automatically emphasize names by wrapping them in underscores:
Tim Berners-Lee -> _Tim Berners-Lee_
Automatically fix false apostrophes:
it's -> it’s
LLMs are not always consistent with typographic preferences. Even flagship models often ignore editorial instructions, resulting in incorrect apostrophes. A more deterministic solution is TypographizerJS, a fork of Typographizer by Frank Rausch, which can post-process generated text.
Conclusion
This experiment reminded me how quickly an idea can go from a small annoyance (“why is typing on my phone so slow?”) to a working prototype using today’s AI tools.
It doesn’t take much: a simple system prompt, a lightweight model, and a bit of glue code can improve the writing experience significantly.
The best AI features don’t feel like AI—they let you focus on your thoughts rather than mechanics.
Of course, a classic spell-checker could also solve the problem, but LLMs offer much more. Every new line is an opportunity for AI to correct, enhance, translate, or fact-check your text. In a real application, I would probably think about less immediate ways to manipulate text: suggested changes, change history, annotations, highlights, undo, etc. — but that’s food for another experiment.