Engineering notes
Technical decisions, tradeoffs, and lessons from building smplkit.
Python Coding Standards That Make Collaboration Easier
Coding standards documents often feel like bureaucracy — a list of rules that exists to exist, written by someone who felt strongly about snakecase and wanted everyone to know it.
End-to-End Testing a Multi-Language SDK Platform
Unit tests tell you that components work in isolation. Integration tests tell you that components work together within a service. Neither tells you that a TypeScript SDK talking to the production A...
What Happens to Your Data When You Delete Your Account
Account deletion is one of those features that seems straightforward and isn't. Delete the account, delete everything associated with it — what's hard about that?
Why We Chose ECS Fargate Over Kubernetes
The first serious infrastructure conversation on any new microservices project eventually arrives at container orchestration. In 2024, the options crystallized around two choices: Kubernetes EKS on...
Flat Keys, Real Inheritance: How Smpl Config Works
Configuration management at scale has two competing failure modes. The first is configuration sprawl — the same value defined in forty places, nobody sure which one is authoritative. The second is ...
Real-Time Log Level Control Without Touching Your Code
The typical debugging cycle for production log issues involves SSH, a grep through recent logs, and either resigning yourself to INFO-level noise or deploying a code change to enable DEBUG. Neither...
Designing Feature Flags That Don't Require Redeployments to Change
Feature flags sound simple until you design them seriously. A boolean switch — feature on or off — is the most obvious implementation, but it's almost immediately insufficient. Teams want string va...
How We Ship Type-Safe SDK Clients for Every Language We Support
We support six programming languages in our SDKs: Python, TypeScript, Go, Java, C, and Ruby. Keeping all six in sync with the API, with consistent naming, consistent types, and consistent behavior,...
Shared Code Without a Monorepo: How We Built smplkit-core
When you have multiple Python services that need to share code — data models, utilities, middleware, error handling — you have a few architectural options. We could have gone monorepo, colocating a...
How We Prevent Tenants from Seeing Each Other's Data Without Thinking About It
Every SaaS product that serves multiple customers from a shared database has to solve the same problem: make sure tenant A can never see tenant B's data, regardless of how clever or careless the ap...
Why We Ditched Next.js for Our Developer Console
Next.js is a great framework. We used it wrong.
JSON:API — Why We Picked a Standard Instead of Rolling Our Own
Every API needs a response format. The question is whether you design your own or adopt an existing standard.
Schema Conventions That Let AI Agents Write Correct Code
We use AI coding agents extensively at smplkit. Not as a novelty — as a core part of the development workflow. Claude Code writes implementation code, runs tests, monitors CI, and auto-remediates f...
Why Alembic Over Liquibase for a Python FastAPI Stack
If you're building a Python backend with SQLAlchemy and you need database migrations, Alembic is the obvious choice. It's SQLAlchemy's companion migration tool, built by the same author, deeply int...
Designing API Key Auth for a Multi-Product Developer Platform
API key authentication seems simple until you're designing it for a platform with multiple products, multiple environments, and two distinct types of API consumer.
Why We Chose PostgreSQL Over DynamoDB for a Multi-Cloud SaaS Platform
Every SaaS platform needs a database. For smplkit, the choice was more constrained than it first appeared — not because there aren't enough options, but because multi-cloud portability eliminated m...
Replacing Redoc with Scalar: Lessons in API Documentation UX
We made a mistake. Not a catastrophic one — the kind where you pick a reasonable tool, integrate it, and then discover through use that it doesn't fit.
Building a Consistent Icon System for a Product Suite
smplkit has fifteen products. Each one needs an icon that works at every size: the navigation flyout, the product page header, the sidebar in the developer console, marketing materials, and eventua...
SEO Fundamentals for Developer Tool Websites
Most developer tool websites get SEO wrong — not because SEO is hard, but because developers tend to either ignore it entirely or cargo-cult a list of optimizations without understanding why they m...
Email Capture for Static Sites Without a Backend
Before smplkit launched, we needed a way to collect email addresses from developers who wanted to be notified about new products. The marketing site is fully static — no server, no database, no API...
Separating Docs from Marketing: A Developer Platform Pattern
One of the earliest infrastructure decisions for any developer platform is whether documentation lives inside the marketing website or separately. The answer seems obvious — it's all content, put i...
Naming a Developer Tool: Why Lowercase Won
Naming a product is one of those decisions that feels trivial until you realize it touches everything: your domain, your npm package, your import statements, your marketing site, your legal filings...
Information Architecture for a Multi-Product SaaS Platform
Here's a question that sounds simple until you try to answer it: how do you organize a website for a product that doesn't exist yet?
Choosing AWS Amplify for a Developer Platform Marketing Site
Every developer tool needs a website. And every developer building that tool has to resist the urge to over-engineer it.