Technical
Engineering notes from the team — TypeScript patterns, monorepo trade-offs, infrastructure decisions and the build tooling behind Procaptcha.
Technical · A WebSocket upgrade walked straight past our Lambda@Edge An attacker sent plain HTTP/1.1 requests dressed up as WebSocket upgrades to our CloudFront distribution, and they reached the origin without our viewer-request Lambda@Edge function seeing them. Any site that keeps its security logic in a viewer-request function may have the same gap, and AWS WAF can close it.
Technical · We stopped throwing errors in TypeScript and used Rust's Result instead A TypeScript function signature tells you everything except how it can fail. Rust solved this years ago by putting failures in the return type with Result, and TypeScript's discriminated unions and type guards make the same pattern a natural fit. We published ours as @prosopo/result.
Technical · GitHub quietly broke our free CI overflow Giving a self-hosted runner the ubuntu-latest label used to let it share jobs with GitHub's hosted runners, so when the Actions minutes ran out our own machines picked up the slack. That stopped working in mid-2025, without an announcement. The workarounds left all cost something: a token, a billed minute per run, a cluster to run, or a bigger bill.
Technical · Docker was hiding half a terabyte on our CI runner One CI runner's disk kept filling up. docker system prune freed 254GB, but another 238GB was hiding in old images, orphaned volumes and log files that no prune touches. Each of those needs its own command, and two of them can delete data you can't get back.
CAPTCHA · How to Stop PHP Form Spam (Without a Plugin) If your PHP mail script is being abused by bots, stop the bot before mail() runs — server-side CAPTCHA verification in a few lines of PHP, via Procaptcha.
Technical · How to Add CAPTCHA to Fastly CDN Learn how to integrate Procaptcha with Fastly CDN to protect your website from bot attacks while maintaining performance and user privacy.
Technical · We suffered MongooseJS so you don't have to We investigate how MongooseJS's type safety can silently add bugs to your code base.
CAPTCHA · We cut our Mongo DB costs by 90% by moving to Hetzner We moved MongoDB Atlas off AWS and onto self-hosted Hetzner boxes — 90% cost cut, no performance loss. Here's the setup, the Ansible, and what broke.
Technical · Reactive Frameworks Cheatsheet - React, Vue, Svelte and Angular
Technical · PHP Views Package - Templating Made Easy with Blade and Model-Driven Approach
Technical · Streamlining Releases: Building Scalable CICD Pipelines with Changesets Overcome common challenges and scale your CICD pipelines for predictable versioning, releases and deployments.
Technical · Independent vs Locked Versioning in a Workspace Locked vs independent versioning in a monorepo workspace — the tradeoffs on release cadence, dependency drift and CI overhead, and which one fits your team.
Technical · Mastering Versioning: A Guide to Software Stability Semver rules, dependency traps and the pitfalls that break stable builds — how we manage versioning at Prosopo without wrecking downstream consumers.
Technical · Monorepo vs Multirepo Architecture: How to Decide? Monorepo vs multirepo — tradeoffs on tooling, CI cost, dependency drift and team autonomy. Which one actually fits your project, and when to switch.
CAPTCHA · How to Test Your Ansible Playbooks Locally Testing your Ansible playbooks locally can save you time and effort. Here are some tips to help you get started.
CAPTCHA · tsx vs ts-node: Time to Drop ts-node for tsx tsx vs ts-node compared: why tsx runs TypeScript faster than ts-node, and how to migrate your Node.js scripts away from ts-node today.
CAPTCHA · actions/cache@v3 restore: GitHub Actions Cache Fix Fix GitHub Actions caching with actions/cache@v3 and actions/cache/restore: share caches across branches and evict old caches faster.
CAPTCHA · TypeScript: Branded Types How to brand TypeScript types for norminal typing, providing an automated and easy-to-use way of making a type nominal.
Technical · Using Vite To Rebuild Local Dependencies in an NPM Workspace Vite ignores local workspace packages because they sit outside its module graph — the config trick that forces Vite to rebuild sibling npm packages.
CAPTCHA · Vite: How to handle .node files Vite can't bundle .node native binaries — it treats them as raw JS and blows up. Our custom rollup plugin that copies .node files through the build.
CAPTCHA · TypeScript: Mapped Type Magic TypeScript mapped types can make Cat === Dog — a weird paradox. How to brand identical structural types so the compiler can tell them apart.
Technical · How to deploy Procaptcha on your website or app How to switch from Google's reCAPTCHA to Prosopo Procaptcha and protect your website or app from bots for free.See what's reaching your site
A Bot Exposure Assessment is a 30-minute call with an engineer. We look at your traffic, show where your current setup leaves gaps, and agree how a trial would be judged. Nothing to install first.