DEV Community

TextKit
TextKit

Posted on

I Built 37 Free Browser-Based Tools with Flask and No JavaScript Framework

No React. No Next.js. No build step. No node_modules.

I built TextKit — a collection of 37 free online tools for text processing, data cleaning, and developer utilities — using Flask, Tailwind CSS via CDN, and vanilla JavaScript. The entire project starts with python app.py.

Here's the stack, the architecture decisions, and what I've learned.

The stack

Python + Flask       → serves HTML via Jinja2 templates
Tailwind CSS CDN     → styling, zero build config
Vanilla JavaScript   → all tool logic, 100% client-side
Markdown + YAML      → blog system
Render               → hosting
Cloudflare           → DNS + caching
Umami                → privacy-friendly analytics
Enter fullscreen mode Exit fullscreen mode

No database. No auth system. No npm. The entire deployment is a Flask app serving static-ish pages.

Why no framework?

Because these tools don't need one.

A JSON formatter takes text input, calls JSON.parse() and JSON.stringify(), and displays the result. A password generator calls crypto.getRandomValues() and builds a string. A diff checker runs an LCS algorithm on two arrays of strings.

Every single tool follows the same pattern: input → transform → output. A <textarea>, an addEventListener('input', ...), and a function. React adds a virtual DOM, a component lifecycle, a build system, and 40KB of JavaScript to do the same thing that 20 lines of vanilla JS handles.

I'm not anti-framework. I use React at work. But for this project, a framework would have been overhead with zero user benefit.

Architecture

Every tool is a Jinja2 template that extends base.html:

templates/
  base.html                     → nav, footer, fonts, theme CSS
  index.html                    → homepage with search + tool grid
  tools/
    json-formatter.html         → extends base.html
    password-generator.html     → extends base.html
    regex-tester.html           → extends base.html
    ... (37 tools)
Enter fullscreen mode Exit fullscreen mode

The Flask app is dead simple:

@app.route('/json-formatter')
def json_formatter():
    return render_template('tools/json-formatter.html')
Enter fullscreen mode Exit fullscreen mode

One route per tool. The TOOLS registry is a list of dicts that drives the homepage grid, sitemap, and navigation. Add a tool to the list, it shows up everywhere.

All logic is client-side

Hard rule from day one: no text data goes to the server. Ever.

Users paste sensitive stuff into text tools — API keys, database queries, internal emails, customer data. If any of that hits a server, you've created a trust and liability problem. Everything runs in the browser, and users can verify this by disconnecting from the internet — every tool still works.

For most tools this is trivial. But a few pushed the limits:

Diff Checker — implements a full Longest Common Subsequence algorithm with character-level highlighting within changed lines. The LCS matrix is O(m×n) which means comparing two 5,000-line texts creates a 25 million cell array. Works, but I added a warning for large inputs.

Regex Tester — runs user-supplied patterns via new RegExp(). Zero-length matches like \b cause infinite loops in the exec() loop if you don't handle them:

while ((match = regex.exec(text)) !== null) {
  matches.push(match);
  if (match[0].length === 0) regex.lastIndex++;  // prevents infinite loop
}
Enter fullscreen mode Exit fullscreen mode

CSV Parser — you might think parsing CSV is text.split(','). It's not. Real-world CSV has quoted fields with commas inside, escaped quotes (double-quote within a quoted field), and newlines within quoted fields. The parser is a proper state machine.

Time Zone Converter — uses the browser's Intl.DateTimeFormat API for all timezone calculations. No timezone library, no database file. Modern browsers know every IANA timezone and handle DST automatically.

The tool list

37 tools across 9 categories:

Delimiter tools (10): Column↔Comma, Column↔Tab, Column↔Semicolon, Column↔Pipe, Column↔Space — all bidirectional

Text transform (5): Case Converter, Trim Whitespace, Add Prefix/Suffix, Number Lines, Slug Generator

Data cleaning (3): Remove Duplicates, Remove Blank Lines, Sort Lines

Text analysis (2): Word Counter, Count Lines

Text extraction (4): Extract Emails, URLs, Numbers, Phone Numbers

Generators (3): Password Generator, UUID Generator, Lorem Ipsum Generator

Developer tools (5): JSON Formatter, Regex Tester, Diff Checker, Epoch Converter, Time Zone Converter

Encode/Decode (3): Base64, URL Encode/Decode, Text to Binary

Data formats (2): CSV to JSON, JSON to CSV

SEO as architecture

Each tool page has:

  • Unique title and meta description targeting specific search keywords
  • 200+ word "what is this tool" section
  • FAQ section with <details>/<summary> tags
  • FAQPage schema markup (JSON-LD) — earns rich snippets in Google
  • WebApplication schema
  • Related tools section with internal cross-links
  • Canonical URL and OpenGraph tags

The SEO content is roughly 70% of each page. The tool itself is a textarea and some buttons. Google ranks pages for informational queries, and the tool functionality keeps users engaged and builds backlinks organically.

I also run a blog with Markdown files parsed via a simple Flask route. Each post targets a "how to" keyword and links to the relevant tool. The blog posts rank for informational queries, drive traffic, and pass internal link authority to the tool pages.

What I'd do differently

Build the high-traffic tools first. I started with delimiter converters because they were simple. But JSON Formatter (350K monthly searches) and Password Generator (450K monthly searches) should have been first — more search volume, earlier indexing.

Don't use Tailwind CDN in production. It works and it's zero-config, but it loads the entire Tailwind stylesheet (~300KB). Self-hosting a purged CSS file would be much smaller. Haven't gotten around to it.

SEO content takes longer than building tools. Writing the "what is" sections, FAQs, and schema markup for 37 tools took more hours than writing the JavaScript. Plan for that.

Current status

  • 37 tools live
  • 12 blog posts
  • Indexed and ranking in Google (averaging position 20 and climbing)
  • Thermal receipt theme — because developer tools should have personality

Everything is free, no accounts, no tracking. Check it out: textkit.dev

Happy to answer questions about the stack, the SEO approach, or any of the tool implementations.

Top comments (0)