Astal Creates — a product studio

Thoughtful software, built all the way through.

I design, engineer and operate web applications, browser products, dashboards and automated systems, from the first problem to the live product.

Selected work

Seven landmarks along the river.

Live web applications, browser products, a private spend analyser, a dashboard and an experiment. Each one carried from first problem to shipped product.

01 · Web Application

PredictsWorld

Predict every World Cup 2026 match and compete with friends on live leaderboards.

400+real users
Live · 400+ users
PredictsWorld — product screenshot
Algo Trading Platform — product screenshot
02 · Dashboard

Algo Trading Platform

Autonomous options-trading system with real-time risk controls, multi-channel alerts, and a live dashboard.

490+automated tests
In Development · Private
03 · Web Application

Kosh

A private, browser-only spend analyser for Indian bank statements.

100%parsed in-browser
Live · In development
Kosh — product screenshot
Adobe Tags Exporter — product screenshot
04 · Web Application

Adobe Tags Exporter

Export an Adobe Launch container to Excel and audit it, entirely in-browser.

36weighted checks
Live
05 · Browser Extension

PrivacyShield

A zero-network Chrome extension that blurs sensitive on-screen data before you share your screen.

174unit tests
Live on Chrome Web Store
PrivacyShield — product screenshot
TrackerScope — product screenshot
06 · Browser Extension

TrackerScope

See which trackers are watching you on every website, and stop them instantly.

16+tracker platforms
Live on Chrome Web Store
07 · Experiment

Will You Go On A Date?

An animated, interactive proposal flow with a "No" button that refuses to be clicked.

0dependencies
Live
Will You Go On A Date? — product screenshot
Capabilities

One trunk, five branches.

End-to-end product development, from interface to infrastructure. Select a technology to see where it actually grows.

Frontend
Backend & Data
Browser Products
Automation & Systems
Testing & Delivery
Approach

Four stones across the water.

How a product crosses from an idea to something that runs in production, and stays running.

01

Understand

Start from the real problem and the person who has it. Pin down the job to be done, the constraints, and what 'good' actually means before writing a line of code.

  • Problem framing
  • Constraints & edge cases
  • Success criteria
02

Architect

Design the data model, boundaries, and failure modes up front. Decide where state lives, what's authoritative, and how the system behaves when things go wrong.

  • Data model
  • System boundaries
  • Failure-mode design
03

Build

Ship in typed, testable increments. Server-first where it belongs, interactive where it earns it, with automated tests guarding the logic that matters.

  • Typed increments
  • Automated tests
  • Server-first rendering
04

Ship & operate

Deploy, monitor, and keep it running. Real traffic surfaces the hard bugs, connection pools, worker restarts, irregular data, and I own them end to end.

  • Deploy & monitor
  • Alerting
  • Debug under real load
Field notes from production

The hard problems, recorded.

Real issues met under production load, kept as short journal entries: situation, cause, decision, result.

PredictsWorld

PostgreSQL connection-pool exhaustion

Situation

Under production traffic the app hit intermittent 500s and pages that loaded forever.

Cause

PostgreSQL connection-pool exhaustion against Supabase's transaction pooler (a hard 200-connection cap): the pooled postgres.js client was re-created per request instead of cached across warm serverless invocations, and postgres.js has no built-in wait-timeout, so a saturated pool made server components hang rather than fail.

Decision

Cache the pooled client across invocations, tune pool size and idle_timeout / connect_timeout, wrap hot-path DB calls in an application-level timeout, and add Next.js error boundaries.

Result

Failures now surface as errors with a retry UI instead of infinite spinners, and the pool no longer exhausts under load.

Algo Trading Platform

Irregular option-chain strikes

Situation

Naive strike-selection could pick a strike that doesn't exist in the real option chain, or a stale contract with no active market.

Cause

Live option-chain data isn't uniformly spaced, some underlyings mix legacy corporate-action-adjusted strikes with the current grid at irregular intervals, so 'round to the nearest step' arithmetic breaks.

Decision

Select strikes from the broker's actual listed-strike data rather than assumed spacing, with a bounded, liveness-aware search that prefers a genuinely tradeable nearby strike over a numerically-closer illiquid one.

Result

Falls back to an explicit 'no viable contract' state when nothing nearby is tradeable, so a bad chain is never silently misread as a good one.

Kosh

Rebuilding transactions from PDF coordinates

Situation

On real bank PDFs, reprinted column headers, brought/carried-forward markers and a footer disclaimer's phone numbers were leaking into transactions, and one footer line became a phantom transaction that broke the running-balance chain.

Cause

PDF.js returns loosely positioned x/y text fragments, not tables, so rows and columns have to be reconstructed from coordinates, and page-break reprints and footer text sit in the same coordinate space as genuine rows.

Decision

Detect and skip header/footer/balance-forward rows, strip leaked ledger markers while preserving genuine leading-digit references, and reconcile each row's amount against the running balance to recover debit/credit direction.

Result

Verified against a real five-page statement: four phantom rows removed and all balance-mismatch warnings cleared.

PrivacyShield

Manifest V3 service-worker state

Situation

After a service-worker restart, Panic Mode could invert or screen-share protection could leave tabs permanently blurred.

Cause

MV3 service workers are unloaded and restarted at any time, silently resetting in-memory module state like 'is Panic currently on?'.

Decision

Move ephemeral cross-restart state into chrome.storage.session, make every disable path DOM-authoritative (always query and clear tracked elements), and add a monotonic generation counter to invalidate superseded async work.

Result

A desynced flag can never leave a page stuck blurred, and racing profile apply/clear operations no longer clobber each other.

TrackerScope

Tracker detection & instant blocking

Situation

The popup could show 'no trackers' on a tab open for a while, even though the badge still showed a stale count.

Cause

MV3 service workers terminate after ~30 seconds of inactivity, wiping the in-memory Map that held per-tab detection state.

Decision

Serialize the per-tab set of tracker IDs into chrome.storage.session and rehydrate on read; and to make 'Stop' instant on already-running trackers, inject a MAIN-world script that swaps each tracker's live API functions for no-op proxies.

Result

Detection state survives worker restarts within the session, and blocking takes effect immediately without a page reload.

Contact

Where the river opens out.

Have a product in mind, something to build, or a question about one of these? Tell me a little and I'll write back.

astalcreates@gmail.com
What are you looking to build?
Prefer email? astalcreates@gmail.com