An interactive regex tester web app — live match highlighting, capture-group inspection, named-group support, substitute mode, savable pattern library, and a built-in cheatsheet. Privacy-first: every pattern, every test string, every saved snippet stays in your browser's localStorage. No accounts, no backend, no telemetry.
Most regex playgrounds either ship with a heavyweight backend, or they pop up a paywall the second you want to save a pattern. finch is a tiny, statically-rendered Next.js app that does exactly one thing well:
- Type a pattern → see matches highlighted as you type.
- Click a row → expand its numbered captures and named groups.
- Switch to substitute mode → preview replacements live, with
$1,$2,$<name>references. - Save patterns to a personal library (per browser).
- Reach for a built-in cheatsheet when you forget what
\bdoes.
It's the regex utility I want sitting in a browser tab while I write code — fast, focused, and offline-friendly.
- Live evaluation with a 250 ms execution budget and a 5 000 match cap so a pathological pattern can't lock the UI.
- Capture groups + named groups rendered in a clean expandable table.
(?<ts>...),(?<level>...),(?<msg>...)— they all show up as inspectable rows. - Substitute mode — paste a replacement string with
$1,$<name>,$&and watch it apply across the whole test text in real time. - Pattern library — name a pattern, hit save; it lives in
localStorageuntil you delete it. One click to load it back later. - 10 built-in samples — email, URL, IPv4, ISO date, UUID, hex color, semver, long words, log-line named groups, and a snake → kebab substitute.
- Cheatsheet — character classes, anchors, quantifiers, groups, lookarounds, and replacement syntax — all on one page.
- Light / dark / system theme with a no-flash hydration script.
- Strict TypeScript, ESLint clean, production build clean.
![]() |
![]() |
![]() |
![]() |
git clone https://github.com/Dianaekaaa/finch.git
cd finch
npm install
npm run dev
# open http://localhost:3000For a production build:
npm run build
npm run start- Next.js 16 (App Router, Turbopack, React 19)
- TypeScript (strict)
- Tailwind CSS 4
- lucide-react for icons
- No backend, no API routes, no third-party analytics
src/lib/regex.ts is the only piece doing real work — it constructs a RegExp with the user's flags inside a try/catch, then walks regex.exec() with a wall-clock deadline (MAX_DURATION_MS = 250) and an iteration cap (MAX_MATCHES = 5000). Every match is converted into a MatchInfo with start/end indices, numbered groups, and named groups, ready to be rendered.
src/hooks/useFinch.ts keeps everything in a single hook: pattern, flags, test text, replace string, saved patterns. State hydrates from localStorage on mount and saves on every change. useMemo keeps evaluation and substituteResult cheap.
The UI is plain React — no global stores, no data fetching layer, no server actions. The whole thing prerenders to a single static HTML file.
finch/
├── src/
│ ├── app/
│ │ ├── layout.tsx — metadata + ThemeProvider + no-flash script
│ │ ├── page.tsx — main layout
│ │ └── globals.css — Tailwind + tiny CSS reset
│ ├── components/
│ │ ├── TopBar.tsx
│ │ ├── PatternInput.tsx
│ │ ├── TestArea.tsx
│ │ ├── MatchTable.tsx
│ │ ├── SubstitutePanel.tsx
│ │ ├── LibraryPanel.tsx
│ │ ├── Cheatsheet.tsx
│ │ ├── ThemeProvider.tsx
│ │ └── ThemeToggle.tsx
│ ├── hooks/
│ │ └── useFinch.ts
│ └── lib/
│ ├── regex.ts — evaluate() + substitute()
│ ├── samples.ts — 10 built-in patterns
│ ├── storage.ts — localStorage helpers
│ ├── types.ts
│ └── cn.ts
├── docs/screenshots/
└── package.json
finch never sends data anywhere. Patterns, test text, and saved snippets stay in localStorage on this device. There is no analytics script, no error reporting, no fetch calls to any external service. You can verify this in DevTools → Network: an empty page load, an empty interaction.
MIT — see LICENSE.



