Tag: accessibility
Mobile Accessibility Is the Case Developers Keep Ignoring
The accessibility argument is made with sufficient frequency in developer conferences and engineering blog posts that it has acquired the character of something everyone agrees with and nobody acts on. Apps ship with missing accessibility labels, unlabeled buttons, broken VoiceOver navigation, and dynamic type support that was added for text elements but forgotten for layout constraints. The gap between the accessibility investment that development teams describe as important and the accessibility state of their shipped applications is among the widest in software development.
Tag: ai
A Feature Store Small Enough to Embed: Point-in-Time Reads for Local and Edge ML
A churn model looks excellent in the notebook and mediocre in production. The model isn’t broken. The training table computed orders_7d with a rolling window over the full history, so some rows counted orders placed after the label date. The serving code, written later in another language, counts a calendar week instead of seven days. One feature, two definitions, and a quiet look into the future. Those are the two bugs a feature store exists to prevent: training-serving skew and label leakage.
An Evidence Graph Built From Extracted Claims Keeps Contradictions Attached to Their Sources
Feed forty articles about a rumored plant restart to a summarizer and you get one smooth paragraph: several outlets report that production will resume in March, though the ministry has pushed back. It reads well. It also throws away what you’d need to act on it. You can’t tell which outlets reported it, whether each had its own source or all copied one wire story, or what the ministry actually said, a denial or a polite refusal to comment.
Context Window Management as a Database: Ask for 12,000 Tokens, Get the Most Useful Ones
An agent is ninety tool calls into a refactor. Step 12 was a grep that returned 52 KB, and all of it is still in the prompt. The user’s instruction from step 1, “never touch db/migrations”, fell out of the window ten steps ago, because the framework drops the oldest messages first. The agent edits a migration. Nothing malfunctioned; the truncation rule did exactly what it was written to do.
Embedded Vector Search Is Crowded: What a One-File Vector Database Needs to Stand Out
You have 40,000 support articles and an app that should offer “similar articles”. Embedded at 768 dimensions in float32, that’s 40,000 × 768 × 4 bytes, about 123 MB of vectors. The standard advice is to stand up a vector database: a service, a port, credentials, a client library and a backup story for 123 MB. A file would do.
Below a few million vectors the server is the overhead, which is why the embedded field filled up fast. So the useful question is what a newcomer brings that the free libraries don’t. My answer is one sharp edge you can state in a sentence, plus measurements the others leave you to make yourself.
PixVerse Closes Series C Extension at $439 Million and Pivots From AI Video Into Games
PixVerse has closed an extension to its Series C, bringing total fundraising in the round to $439 million, and used the announcement to signal a strategic move well beyond the AI video generation market it built its name in. The Singapore-based company is extending its platform into games and interactive entertainment.
The extension pulled in a notably broad investor set. New participants include Alibaba, Lollapalooza Capital, Ivy Capital, Grand Mount Capital, Eastern Bell Capital, Mirae Asset, BlueFocus, and CloudAlpha, alongside returning investors iGlobe Partners and OCBC’s LionX Ventures. The mix of Chinese strategic capital, Korean institutional money, and Singaporean bank-backed venture funding says something about where the AI media stack is being financed — and it is not exclusively in California.
AI in Mobile Apps: What Is Working Beyond the Hype
The integration of AI capabilities into mobile applications has followed the familiar hype cycle pattern: an initial period of breathless coverage about what AI would do for apps, followed by a quieter period of teams discovering which AI features users actually value and which are dismissed as gimmicks within the first week of use. The dust has not fully settled, but the outline of what works is becoming clear.
The AI features that have demonstrated durable user value are mostly not the ones that received the most attention during the hype phase. Large language model chatbots embedded in apps — the most visible AI feature of the 2023-2024 period — have retention profiles that most teams find disappointing. Users try them, find them useful or impressive in isolated interactions, and then forget to use them because the chat interface requires more effort than the specific task typically warrants.
Tag: ai agents
40 Projects Worth Building: SQLite for X, Tiny Infrastructure, MCP Tools and Edge Systems
The most promising territory for a small team isn’t another large framework. It’s the opposite: infrastructure software you can explain in one sentence, ship as one binary or embed as one library, run with almost no operational burden, and that solves one irritating problem unusually well. SQLite and nginx are the right mental models because their appeal is architectural, not just functional: small surface area, predictable behavior, few dependencies, easy deployment, and usefulness far beyond the original use case. (More on that in the SQLite and nginx pattern as a product strategy.)
40 Radically Different Infrastructure Primitives, From Reach and Expect to Ignorance and Stop
This list deliberately leaves “tiny version of Redis, Kafka or SQLite” territory behind. That was the first list of 20 primitives. The more interesting search space is a primitive that introduces a new operation, one developers might eventually feel should have existed all along. Some research paper or niche project has probably explored pieces of these. They’re meant as category-level concepts, not smaller copies of familiar products.
Forty primitives
1. Reach. Store a current state plus transition rules and continuously maintain which states are reachable from here: REACHABLE(current_state). A database answers what is; Reach answers what can happen. Uses: AI agent safety, workflows, infrastructure, manufacturing, cybersecurity attack paths.
Counterfactual Store vs. Markov Chains: From Branching State to Reach, an Engine for Possible Futures
The Counterfactual Store does resemble a Markov chain at the conceptual level. Both deal with states and the possible transitions between them. But a Markov chain is mainly a mathematical model for probabilistic transitions: given that I’m in state A, what’s the probability the next state is B, C or D? And the classic Markov property says the next-state probability depends on the current state, not the full history.
The Counterfactual Store is deterministic branching, not probabilistic transition. If the current application state is A, you create a hypothetical A′, change something, propagate the consequences, inspect the result and throw it away without touching A. No probability needs to be involved anywhere.
Counterfactual Store: A Database That Stores Alternatives, Not Just Facts
One direction that feels genuinely different from the earlier list of 20 primitives is a Counterfactual Store. Adjacent ideas certainly exist. Provenance databases, event sourcing, probabilistic databases, simulation systems and version control all touch pieces of it. But as a deliberately tiny infrastructure primitive, there’s no established category built around this exact abstraction.
Normal databases answer “what is true?” Temporal databases, and Temporal KV, add “what was true?” A Counterfactual Store adds a third basic question: what would be true if X were different?
A Database Where Every Value Remembers Its Source, Confidence and Extraction Time
Somebody pastes a population figure into a shared spreadsheet: 1,234,567. It might have come from a census table, a Wikipedia infobox, a city press release or a model’s summary of one of those, and three weeks later nobody can say which. The paste kept the digits. Everything that made them believable stayed in a browser tab that closed long ago.
A value without provenance is a rumor with a data type.
An Evidence Graph Built From Extracted Claims Keeps Contradictions Attached to Their Sources
Feed forty articles about a rumored plant restart to a summarizer and you get one smooth paragraph: several outlets report that production will resume in March, though the ministry has pushed back. It reads well. It also throws away what you’d need to act on it. You can’t tell which outlets reported it, whether each had its own source or all copied one wire story, or what the ministry actually said, a denial or a polite refusal to comment.
Context Window Management as a Database: Ask for 12,000 Tokens, Get the Most Useful Ones
An agent is ninety tool calls into a refactor. Step 12 was a grep that returned 52 KB, and all of it is still in the prompt. The user’s instruction from step 1, “never touch db/migrations”, fell out of the window ten steps ago, because the framework drops the oldest messages first. The agent edits a migration. Nothing malfunctioned; the truncation rule did exactly what it was written to do.
Cron for AI Agents: Schedules, Timeouts, Overlap Rules and Cost Ceilings in One Config File
A nightly agent job triages new issues. One night an issue arrives with a 400 KB log attached. The agent reads it, a tool call fails, the agent retries, and the loop runs until the month’s token budget is gone. Meanwhile cron, which has no idea what a token is, starts the next run on schedule. Now two copies are fighting over the same issue tracker.
Cron was built for jobs that cost nothing, finish in seconds and do the same thing every time. Agent jobs cost money per token, run for an unpredictable time and can loop. The useful ones are still boring and periodic: summarize what changed in a repo since yesterday, triage new issues each morning, check a competitor’s pricing page weekly. What they need is a scheduler that stays as small as cron and adds four things: a cost ceiling, a timeout that actually kills, an overlap rule, and state carried between runs. Anything past that is an orchestration platform, a different and much larger product.
Facts Should Expire: A Database That Tells an AI Agent When Its Knowledge Has Gone Stale
An agent keeps a memory table, and two rows matter for today’s task: a supplier’s headquarters city, written eleven months ago, and a freight quote, written three hours ago. A SELECT returns both in the same shape. The headquarters is probably still right. The quote may already be wrong. Nothing in either row says so, and the agent repeats both in the same flat tone.
A row has no idea how old its truth is. It might carry a created_at, and a careful person can compute an age from it, but the decay rate belongs to the kind of fact, not to the table. A three-week-old headquarters address is fine. A three-week-old shipping rate is fiction. Server health goes bad in half a minute. No timestamp column holds that knowledge, and nothing forces a query to read it anyway.
Preconfiguration: Writes Coding Agent Setup Files From One Spec and Tests Them on a Clean Machine
Cloud coding agents start each task on a fresh machine. Before the agent can run a single test, something has to install the right runtime, start a database, configure environment variables, and download dependencies. Every platform that runs agents wants those instructions in its own file: Copilot expects a setup workflow, Cursor builds a Dockerfile, other platforms want shell scripts or configuration in other formats. A team that uses two or three agents writes the same setup two or three times, and mistakes usually show up later as an agent session that stalls because a database port wasn’t open or a runtime was the wrong version.
VPN Works: Gives Each AI Agent Its Own Network and a Record of Every Connection
A coding agent spends its day reading text written by strangers: issues on your issue tracker, snippets pasted into prompts, code from repositories, instructions on web pages. One malicious instruction planted in that text can be enough to make an agent send a deploy token somewhere it shouldn’t. On a machine-wide VPN, that request leaves the same way as everything else, and afterwards nobody can say which program sent it.
Cloudflare Kitesurf: An Agent-First Browser That Uses 3-7x Less Memory Than Chromium
Cloudflare shipped Kitesurf on August 6, a web browser it wrote from scratch for AI agents. It runs entirely inside Workers. No Chromium underneath, no container, no headless Chrome process idling in a warm pool waiting for something to do.
The problem it targets is a billing problem. Agents need browsers to do real work, and Chromium is the only serious option, but Chromium was built for a person sitting in front of a screen. Tabs, extensions, device sync, sixty frames a second of smooth scrolling. An agent does not care about any of that. What it cares about is token count, context window, and what the session costs. Handing every agent its own Chromium instance prices most agentic applications out of the web entirely, and leaves browsing to the expensive models that can afford it.
DigitalOcean Launches AI-Native Cloud at Deploy 2026
DigitalOcean has announced the DigitalOcean AI-Native Cloud, positioning itself as the first cloud platform built end-to-end for the inference and agentic era. The launch took place at Deploy 2026, the company’s annual conference for builders, and the platform is available to customers today.
The Problem It’s Solving
AI developers have long been squeezed between two imperfect options: hyperscalers like AWS with enterprise-grade complexity and unpredictable costs, or newer GPU clouds that hand you bare metal and tokens but leave you to wire everything else together yourself. DigitalOcean is pitching its AI-Native Cloud as the third path — a fully integrated stack that handles infrastructure through agents, without the assembly tax.
Verdent Updates AI Platform to Function as a Full Engineering Team for Solo Builders
Verdent has updated its AI-native software platform to operate across the full build cycle — planning, execution, validation, and delivery — rather than stopping at code generation. The update positions Verdent less as a coding assistant and more as a substitute for an engineering team, handling the sequence of decisions and handoffs that typically require multiple people to coordinate.
The gap between a software idea and a shipped product is not usually an ideas problem. It is a labor and coordination problem. Crossing it has historically required hiring engineers, managing sprints, and absorbing the context loss that comes with every handoff. Verdent’s design premise is that AI can now carry that load end-to-end: breaking a goal into tasks, selecting appropriate tooling, writing and testing code, and continuing work asynchronously through Slack or Telegram integrations even when the user is away. Context is retained across sessions, including stack decisions, prior build choices, and current state, so work does not reset between conversations.
Tag: ai app builders
AI App Builders by Use Case: Lovable, Bolt.new, Replit Agent, Softr, FlutterFlow and v0
The AI app builder market is usually ranked as a single leaderboard, which is the wrong shape for it. These tools are not competing for the same job. Sorting them by what they actually produce, and for whom, gives a far more useful picture than any overall score.
Prompt-to-app and full-stack MVPs
These convert natural language into working full-stack applications or rapidly scaffolded prototypes.
Lovable. Built for non-developers, product managers and founders who want fast SaaS prototyping. It generates clean React and Tailwind frontend code paired with built-in Supabase backend infrastructure, authentication and continuous GitHub sync.
AI App Builders Reviewed: Lovable, Base44, Bolt, Replit and v0 Compared
Every one of these platforms will take a sentence and hand you a running application. That part is settled, and it works. What separates them is everything that happens afterwards: what the bill looks like in month three, whether you can take the code somewhere else, and whether the app is open to the internet by default.
They also get lumped into one category when they belong in three. Hosted prompt-to-app builders (Lovable, Base44, Bolt, Replit) generate and host the whole thing. UI-first generators like v0 hand you code and leave hosting to you. Editor and terminal agents such as Cursor and Claude Code sit inside a real repository and assume you can read the output. Security researchers draw the line in the same place, and for a reason: the editor tools require a human to review code before it ships, while the builders generate, execute and deploy with almost no oversight in between.
Verdent Updates AI Platform to Function as a Full Engineering Team for Solo Builders
Verdent has updated its AI-native software platform to operate across the full build cycle — planning, execution, validation, and delivery — rather than stopping at code generation. The update positions Verdent less as a coding assistant and more as a substitute for an engineering team, handling the sequence of decisions and handoffs that typically require multiple people to coordinate.
The gap between a software idea and a shipped product is not usually an ideas problem. It is a labor and coordination problem. Crossing it has historically required hiring engineers, managing sprints, and absorbing the context loss that comes with every handoff. Verdent’s design premise is that AI can now carry that load end-to-end: breaking a goal into tasks, selecting appropriate tooling, writing and testing code, and continuing work asynchronously through Slack or Telegram integrations even when the user is away. Context is retained across sessions, including stack decisions, prior build choices, and current state, so work does not reset between conversations.
Tag: ai coding tools
Cron for AI Agents: Schedules, Timeouts, Overlap Rules and Cost Ceilings in One Config File
A nightly agent job triages new issues. One night an issue arrives with a 400 KB log attached. The agent reads it, a tool call fails, the agent retries, and the loop runs until the month’s token budget is gone. Meanwhile cron, which has no idea what a token is, starts the next run on schedule. Now two copies are fighting over the same issue tracker.
Cron was built for jobs that cost nothing, finish in seconds and do the same thing every time. Agent jobs cost money per token, run for an unpredictable time and can loop. The useful ones are still boring and periodic: summarize what changed in a repo since yesterday, triage new issues each morning, check a competitor’s pricing page weekly. What they need is a scheduler that stays as small as cron and adds four things: a cost ceiling, a timeout that actually kills, an overlap rule, and state carried between runs. Anything past that is an orchestration platform, a different and much larger product.
Preconfiguration: Writes Coding Agent Setup Files From One Spec and Tests Them on a Clean Machine
Cloud coding agents start each task on a fresh machine. Before the agent can run a single test, something has to install the right runtime, start a database, configure environment variables, and download dependencies. Every platform that runs agents wants those instructions in its own file: Copilot expects a setup workflow, Cursor builds a Dockerfile, other platforms want shell scripts or configuration in other formats. A team that uses two or three agents writes the same setup two or three times, and mistakes usually show up later as an agent session that stalls because a database port wasn’t open or a runtime was the wrong version.
VPN Works: Gives Each AI Agent Its Own Network and a Record of Every Connection
A coding agent spends its day reading text written by strangers: issues on your issue tracker, snippets pasted into prompts, code from repositories, instructions on web pages. One malicious instruction planted in that text can be enough to make an agent send a deploy token somewhere it shouldn’t. On a machine-wide VPN, that request leaves the same way as everything else, and afterwards nobody can say which program sent it.
Cloudflare Worker Previews Setup: Which Bindings Isolate Per Branch and Which You Configure Yourself
Cloudflare shipped Worker Previews today, and the headline is easy to state. Every git branch gets its own running Worker, with its own URL, its own config, its own logs, its own traces. You run npx wrangler preview, and the branch you’re sitting on becomes something you can open in a browser and click through. Cloudflare says you can run hundreds of them side by side without them touching each other or production.
AI App Builders Reviewed: Lovable, Base44, Bolt, Replit and v0 Compared
Every one of these platforms will take a sentence and hand you a running application. That part is settled, and it works. What separates them is everything that happens afterwards: what the bill looks like in month three, whether you can take the code somewhere else, and whether the app is open to the internet by default.
They also get lumped into one category when they belong in three. Hosted prompt-to-app builders (Lovable, Base44, Bolt, Replit) generate and host the whole thing. UI-first generators like v0 hand you code and leave hosting to you. Editor and terminal agents such as Cursor and Claude Code sit inside a real repository and assume you can read the output. Security researchers draw the line in the same place, and for a reason: the editor tools require a human to review code before it ships, while the builders generate, execute and deploy with almost no oversight in between.
Vibe Coding Works Until You Have to Read the Code
Vibe coding is fine for code you’re going to throw away, and most of the fighting about it is really people disagreeing about which code that is.
Last month I needed a script to pull a CSV off a shared drive, reshape three columns, and push the rows into an API. I described it, ran what came back, fixed one wrong column name, and never read the rest. It worked. It ran twice and I deleted it. Reading that code line by line would have cost me an afternoon and bought me nothing.
Verdent Updates AI Platform to Function as a Full Engineering Team for Solo Builders
Verdent has updated its AI-native software platform to operate across the full build cycle — planning, execution, validation, and delivery — rather than stopping at code generation. The update positions Verdent less as a coding assistant and more as a substitute for an engineering team, handling the sequence of decisions and handoffs that typically require multiple people to coordinate.
The gap between a software idea and a shipped product is not usually an ideas problem. It is a labor and coordination problem. Crossing it has historically required hiring engineers, managing sprints, and absorbing the context loss that comes with every handoff. Verdent’s design premise is that AI can now carry that load end-to-end: breaking a goal into tasks, selecting appropriate tooling, writing and testing code, and continuing work asynchronously through Slack or Telegram integrations even when the user is away. Context is retained across sessions, including stack decisions, prior build choices, and current state, so work does not reset between conversations.
Tag: android
Mobile App Performance: The Five Metrics That Decide Retention and Store Ratings
Performance work in mobile development wastes more effort than almost any other kind of engineering. Teams burn sprints shaving milliseconds off benchmarks that no user will ever feel. Meanwhile the problems that actually make people uninstall, the freezes, the janky feeds, the phone that’s dead by 4pm, sit in the backlog because nobody put a number on them.
The gap between what’s easy to measure and what users care about is wide. Closing it starts with picking the right metrics.
Mobile Accessibility Is the Case Developers Keep Ignoring
The accessibility argument is made with sufficient frequency in developer conferences and engineering blog posts that it has acquired the character of something everyone agrees with and nobody acts on. Apps ship with missing accessibility labels, unlabeled buttons, broken VoiceOver navigation, and dynamic type support that was added for text elements but forgotten for layout constraints. The gap between the accessibility investment that development teams describe as important and the accessibility state of their shipped applications is among the widest in software development.
Testing Mobile Apps at Scale Without Losing Your Mind
Mobile testing is harder than web testing for reasons that are partly technical and partly organizational. The technical reasons: the diversity of physical devices, OS versions, screen sizes, and hardware configurations that a production mobile app must run on is several orders of magnitude larger than the browser matrix that web applications face. The organizational reasons: mobile development cycles historically moved faster than testing infrastructure could keep pace with, producing teams that ship without adequate test coverage and accumulate testing debt that compounds with each release.
App Store Optimization in 2026 Is a Different Game Than It Was
App Store Optimization was, in its early form, a relatively straightforward keyword game. Include the right terms in your app title and description, achieve a certain volume of downloads and ratings, and the app store algorithm would surface your app to relevant searches. The practitioners who figured this out first made significant money. The techniques spread, the competition intensified, and the algorithm changed — as algorithms always do when they are being gamed at scale.
Cross-Platform vs Native: The Honest Assessment Nobody Gives You
The cross-platform vs native debate has a quality problem: the people most qualified to give objective assessments have financial or professional stakes in one answer. Agency developers who charge by the hour prefer native because it doubles the billable work. Cross-platform framework vendors publish benchmark comparisons designed to minimize the gaps between their output and native. Native platform advocates at Apple and Google have obvious incentives to characterize cross-platform output as inferior.
Mobile Security: What Developers Consistently Get Wrong
Mobile security vulnerabilities cluster in a predictable set of categories. The same mistakes appear in security audits of consumer apps, enterprise apps, and fintech apps with equal regularity. The recurrence of the same errors across different teams and different organizations suggests that the failures are not primarily due to ignorance — most mobile developers are aware that security matters — but to a gap between security knowledge and the specific engineering practices that translate that knowledge into secure code.
Jetpack Compose Is Winning Android UI Development
Google’s transition of Android UI development from the XML layout system to Jetpack Compose has been, by the standards of platform UI framework migrations, unusually smooth. Compose became stable in August 2021. By 2024, it was the recommended approach for new Android development. In 2026, the question for Android teams is no longer whether to adopt Compose but how to manage the migration of existing View-based codebases.
The comparison with SwiftUI is instructive. Both frameworks launched within two years of each other, both represent declarative replacements for older imperative UI systems, and both have faced criticism for gaps between their initial capabilities and the full feature set of what they replaced. Compose has navigated this transition with fewer of the minimum-API-level constraints that limit SwiftUI’s adoption curve, because Android’s broader device compatibility requirements have historically pushed Google toward more conservative backward compatibility policies.
Swift vs Kotlin: The State of Native Mobile Development in 2026
The question of whether to build natively for iOS and Android or to abstract across both platforms with a cross-platform framework has occupied mobile development teams for more than a decade. The answer has not settled. What has settled is the character of native development itself — and in 2026, Swift and Kotlin have each reached a maturity that makes the native argument significantly stronger than it was five years ago.
Tag: app stores
Apple's US Link-Out Fee Is Zero Until a Judge Sets It, and Apple Is Asking for Up to 15%
If your iOS app sells anything digital in the US, you can send users to your own web checkout today and Apple takes nothing from that sale. That has been true since the contempt ruling in Epic v. Apple in April 2025, and it still holds while a court works out what Apple may charge instead. Apple’s opening bid is 15%. Epic’s answer is close to zero.
For developers the window is open now, and it won’t stay free forever. What you build in the meantime should hold up whichever number the court lands on.
The Side Project App Is Not Dead. The Side Project App Business Is.
The romantic narrative of the solo developer who builds an app in nights and weekends, publishes it to the App Store, and generates meaningful income from passive sales is not entirely false. It is sufficiently true in enough specific cases to sustain the mythology and sufficiently rare to make the mythology dangerous as a planning assumption.
The structural conditions that made the App Store a viable path to meaningful passive income for individual developers in 2010 to 2015 have changed. The App Store had fewer apps. Discovery was less competitive. Users were more willing to pay upfront for apps they had not tried. The apps that met a basic need in a well-executed way could find their audience without significant marketing investment.
App Store Optimization in 2026 Is a Different Game Than It Was
App Store Optimization was, in its early form, a relatively straightforward keyword game. Include the right terms in your app title and description, achieve a certain volume of downloads and ratings, and the app store algorithm would surface your app to relevant searches. The practitioners who figured this out first made significant money. The techniques spread, the competition intensified, and the algorithm changed — as algorithms always do when they are being gamed at scale.
The Subscription Model Reckoning Is Hitting Mobile Apps Hard
The subscription model’s dominance of mobile app monetization was, until recently, treated as a settled question. One-time purchases were dead. Advertising was privacy-constrained and algorithmically contested. Subscriptions provided predictable revenue, lower upfront friction, and the renewal economics that made customer lifetime value calculations favorable. Every growth deck from 2018 to 2022 told the same story about subscriptions being the obvious answer.
The reckoning that followed was predictable to anyone paying attention to the demand side of that story. Users had subscribed to enough things. The subscription fatigue that entertainment services experienced — as the number of streaming subscriptions a household maintained reached and exceeded what they were willing to pay — extended to software. Productivity apps, fitness apps, photo editors, and note-taking tools all compete for a monthly budget that users have become conscious of in ways they were not during the subscription model’s initial adoption phase.
The App Store's 30 Percent Problem Is Not Going Away Quietly
Apple’s App Store commission structure has been the subject of regulatory scrutiny, antitrust litigation, developer revolt, and congressional testimony for five years. The outcome of all this attention is a commission structure that has changed at the margins while remaining fundamentally intact at its core. The 30 percent standard rate — reduced to 15 percent for developers earning under a million dollars annually and for certain subscription renewals — continues to apply to the overwhelming majority of App Store revenue.
Tag: architecture
Kafka for One Machine: An Embedded Event Log With Offsets, Compaction and No Broker
A desktop app wants an undo history that survives a crash. An edge gateway buffers sensor readings while its uplink is down and has to replay them, in order, once the link is back. An AI agent writes down every action it takes so a bad run can be replayed later. All three are the same data structure: an append-only sequence of records, plus readers that remember where they stopped. Kafka is that structure, and also a cluster, partitions and the people who tune them.
Mapping Every Dependency to the Features That Break If It Disappears Tomorrow
Run npm ls --all on a mid-sized web app and you get a tree that scrolls for pages. It’s accurate and complete, and on the morning a maintainer deletes a package it tells you almost nothing. You can see that tiny-util sits three levels down. You can’t see whether losing it breaks the checkout page or a script nobody has run since spring.
A dependency tree answers “what do I depend on”. The question that matters is “what breaks, and for whom, if this package vanishes or turns hostile”. They need different data. The tree comes from a lockfile. The answer comes from your own source: which functions call the package, which routes, commands and jobs those functions serve, and how much code would change to replace it. A tool that produced that for every package would turn dependency management from an inventory into something a product owner can read.
One Binary, One File, No Daemon: The SQLite and nginx Pattern as a Product Strategy
Compare two quickstarts. The first says to install Docker, bring up a compose file with a database, a cache and a worker, create an account, and paste a token into an env file. The second says to download one file and run it. Both tools might solve the same problem. Only one of them survives an evaluation that lasts ten minutes.
The second quickstart is a product decision, made in the architecture. SQLite and nginx made it decades ago, and Caddy, DuckDB, ripgrep, jq and Hugo have made it again in their own corners. Small surface area, few dependencies and one artifact to copy work as an adoption strategy. For a one-person or AI-assisted project they also work as the only scope control that holds up. That’s the claim, and the rest of this post tries to break it.
Spreadsheet Recalculation Inside a Database: Derived Values That Track Their Own Dependencies
A line item’s quantity goes from 4 to 5. The order subtotal should change, and so should the tax, the order total, the customer’s lifetime value and the regional revenue figure on a dashboard. Which of those actually update depends on which code path made the edit, because each one gets recomputed somewhere different: the checkout handler, the invoice renderer, a nightly job, a SQL view somebody wrote for finance. Every copy of the formula is another chance for two screens to disagree.
Nine Apps Worth Coding, and the Hard Part Buried in Each One
Every app idea has a boring 90% and a nasty 10%. The boring part is CRUD, auth, a settings page, Stripe. The nasty part is the one subsystem that decides whether the thing works at all, and it’s usually not the part that looks hard in the pitch. Below are nine builds worth attempting, with the nasty 10% named up front so you can decide whether you want to spend your weekends there.
Application Performance Optimization: Where Most Teams Waste Their Time
A team spends three weeks rewriting a hot loop in Rust bindings, shaves forty milliseconds off a function that runs once per request, and ships it. The page still takes four seconds to load. Nobody profiled first. That’s the pattern behind most performance work that goes nowhere: real effort, wrong target.
Optimization only pays off when you know where the time actually goes, and that’s rarely where intuition points. Developers tend to suspect their own code, because that’s the part they wrote and the part they can picture running slowly. The database, the network, the third-party API call buried in a middleware layer — those stay invisible until you measure them.
Building Offline-First Mobile Apps Is Harder Than It Looks and Worth It
The default architecture for most mobile applications treats network connectivity as a reliable precondition. API calls are made on demand. Failures produce error states. The user waits for responses. This architecture produces apps that work acceptably on fast, reliable connections and badly on slow, intermittent, or absent connections — which describes the conditions under which many mobile users actually use apps.
Offline-first architecture inverts this assumption. The app reads from and writes to local storage first. Network synchronization happens in the background, opportunistically, whenever connectivity permits. The user experience is fast and available regardless of network state. The complexity is in the synchronization layer, which most teams underestimate significantly before they build it.
The Mobile Backend Dilemma: Firebase, Supabase, or Build Your Own
Every mobile app that does anything interesting eventually needs a backend. Authentication, data storage, push notifications, file uploads, real-time updates — the list of backend requirements grows quickly once an app moves beyond a local-only experience. The decision of how to provide that backend is one of the most consequential architectural choices a mobile development team makes, and it is one that becomes substantially harder to reverse after significant user data has accumulated.
Tag: backend
A Background Job Queue in One SQLite File Covers What Most Apps Deploy Redis For
A signup handler has to send a welcome email, and sending it inline puts a third-party API call inside your request. So you move it into a background job, and the usual next step is Redis, a client library, a worker process, a dashboard, and a note in the deploy docs about what happens to queued jobs when Redis restarts without persistence. If the app runs on one machine, you’ve added a second stateful service to look after a table’s worth of data.
An Embedded Workflow Engine With Five Primitives: Trigger, Condition, Action, Wait and Retry
A user signs up on Monday. If they haven’t activated by Wednesday, you send a nudge email, and if the email provider times out, you try a few more times before flagging the account. That’s the whole spec. Most teams build it as a cron job that scans for users in the wrong state, a nullable nudge_sent_at column and a retry loop written late on a Friday. It holds until the cron overlaps itself, or a deploy lands mid-loop, or the provider times out after actually sending the message and one customer gets three emails.
Redis Semantics Without Redis: An Embedded State Engine for Counters, Leases and TTLs
A command-line tool should run only one copy of its nightly export at a time. A small web app wants to cap each user at 60 requests a minute. A desktop app needs to remember when it last synced. All three are state: an integer, a timestamp, an owner. All three usually get solved by adding Redis, because Redis has the verbs for them: INCR, SET NX PX, EXPIRE. The app needed the verbs and got a server along with them, a port and a persistence config included.
BareProxy: A Small Go Web Server and Reverse Proxy That Explains Every Routing Decision
Most sites run a thin slice of nginx in front of their application: TLS termination, serving static files from a folder, a couple of routes to a backend service, health checks, and the occasional reload. The configuration grows anyway, one regular expression at a time, until nobody is quite sure which block handles a given URL, and a change that looks safe to one person breaks something in production that another person didn’t know existed.
Precomputing: Keeps Dashboard Answers Ready in a SQLite File as the Data Arrives
Most dashboards ask the same few questions all day long: requests per endpoint, month-to-date usage for one customer, error rates by status code. The usual setup recounts raw rows from scratch on every refresh, or ships every row to a hosted analytics service that bills by the gigabyte. A dashboard that needs to answer quickly on demand either waits for a database query to finish, or pays for a service that stores everything.
The Mobile Backend Dilemma: Firebase, Supabase, or Build Your Own
Every mobile app that does anything interesting eventually needs a backend. Authentication, data storage, push notifications, file uploads, real-time updates — the list of backend requirements grows quickly once an app moves beyond a local-only experience. The decision of how to provide that backend is one of the most consequential architectural choices a mobile development team makes, and it is one that becomes substantially harder to reverse after significant user data has accumulated.
Tag: cloud
DigitalOcean Launches AI-Native Cloud at Deploy 2026
DigitalOcean has announced the DigitalOcean AI-Native Cloud, positioning itself as the first cloud platform built end-to-end for the inference and agentic era. The launch took place at Deploy 2026, the company’s annual conference for builders, and the platform is available to customers today.
The Problem It’s Solving
AI developers have long been squeezed between two imperfect options: hyperscalers like AWS with enterprise-grade complexity and unpredictable costs, or newer GPU clouds that hand you bare metal and tokens but leave you to wire everything else together yourself. DigitalOcean is pitching its AI-Native Cloud as the third path — a fully integrated stack that handles infrastructure through agents, without the assembly tax.
Tag: cloudflare
Cloudflare Worker Previews Setup: Which Bindings Isolate Per Branch and Which You Configure Yourself
Cloudflare shipped Worker Previews today, and the headline is easy to state. Every git branch gets its own running Worker, with its own URL, its own config, its own logs, its own traces. You run npx wrangler preview, and the branch you’re sitting on becomes something you can open in a browser and click through. Cloudflare says you can run hundreds of them side by side without them touching each other or production.
Cloudflare Kitesurf: An Agent-First Browser That Uses 3-7x Less Memory Than Chromium
Cloudflare shipped Kitesurf on August 6, a web browser it wrote from scratch for AI agents. It runs entirely inside Workers. No Chromium underneath, no container, no headless Chrome process idling in a warm pool waiting for something to do.
The problem it targets is a billing problem. Agents need browsers to do real work, and Chromium is the only serious option, but Chromium was built for a person sitting in front of a screen. Tabs, extensions, device sync, sixty frames a second of smooth scrolling. An agent does not care about any of that. What it cares about is token count, context window, and what the session costs. Handing every agent its own Chromium instance prices most agentic applications out of the web entirely, and leaves browsing to the expensive models that can afford it.
Tag: concurrency
Asynchronous Programming in Python: How the Event Loop, Event Queue, and Thread Pool Fit Together
Asynchronous code has a reputation for being confusing, but the core idea is simple: stop waiting. This post starts from zero — no prior async experience assumed — and builds up to the parts people usually find murky: how the event queue, the event loop, and the thread pool connect, and what coroutines, await, futures, tasks, gather, queues, cancellation, and starvation actually mean. Every concept comes with a small, runnable example.
Tag: cross-platform
Cross-Platform vs Native: The Honest Assessment Nobody Gives You
The cross-platform vs native debate has a quality problem: the people most qualified to give objective assessments have financial or professional stakes in one answer. Agency developers who charge by the hour prefer native because it doubles the billable work. Cross-platform framework vendors publish benchmark comparisons designed to minimize the gaps between their output and native. Native platform advocates at Apple and Google have obvious incentives to characterize cross-platform output as inferior.
Flutter's Bet on a Single Codebase Has Mostly Paid Off
Google’s decision to build Flutter on top of Dart — a language that had minimal developer mindshare and an uncertain future when Flutter launched — was a risk that the broader developer community viewed with skepticism. Dart was not JavaScript. It was not Kotlin. It was not a language that developers had strong feelings about because most developers had never used it. Building a cross-platform UI framework on an obscure language was, on its face, an unusual strategic choice.
React Native in 2026: Mature, Imperfect, Indispensable
React Native was announced by Facebook in 2015 with a promise that rewrote the calculus of mobile development: learn once, write anywhere. The promise was qualified from the start — React Native was never write once, run anywhere in the way that early web-based mobile frameworks had claimed to be — but it was credible enough to reshape how a generation of mobile teams made technology decisions.
Eleven years later, React Native is used in production by Microsoft, Shopify, Coinbase, and thousands of smaller organizations. It has survived the emergence of Flutter, the maturation of Kotlin Multiplatform, and a period of internal uncertainty at Meta when the framework’s future was genuinely in question. Its survival reflects something real about the problem it solves and the ecosystem it has built.
Tag: data engineering
A Database Where Every Value Remembers Its Source, Confidence and Extraction Time
Somebody pastes a population figure into a shared spreadsheet: 1,234,567. It might have come from a census table, a Wikipedia infobox, a city press release or a model’s summary of one of those, and three weeks later nobody can say which. The paste kept the digits. Everything that made them believable stayed in a browser tab that closed long ago.
A value without provenance is a rumor with a data type.
A Telemetry Database That Forgets on Purpose Keeps Rollups and Anomalies Instead of Raw Rows
At 300 requests a second, one latency metric adds about 26 million rows a day. Nobody will read most of them again. What people ask for a month later is the p99 per route for last Tuesday, and the one request that took nine seconds. A rule that deletes rows after 30 days throws away both answers. Keeping every row forever pays storage bills for data nobody reads.
The telemetry store worth building decides at write time what has to survive. It folds everything else into coarser buckets on a schedule and keeps the few raw events that carry information, whole. Forgetting becomes part of the schema, declared in a policy, instead of a cron job that deletes by age. This is the argument for reducing data near the source, applied to time series.
A Tiny SQL Engine for JSON Streams Fits Between jq and a Stream Processing Cluster
Your service writes one JSON object per line to stdout, and you want the average cpu for host web-3 over the last five minutes. jq can’t answer that, because it forgets each object once it has printed it and has no idea what “five minutes” means. You can fake both with jq -n 'reduce inputs as $e (...)' plus a timestamp comparison, and you’ll have a script nobody wants to touch twice. DuckDB answers the question in one line, but only against a file as it exists right now. ksqlDB, Materialize, RisingWave, Arroyo and Flink SQL answer it continuously, once you’ve deployed a service and agreed to operate it.
An Embedded Sketch Database: Billions of Events, Megabytes of Storage, Error Bars on Every Answer
Counting unique visitors exactly means remembering every visitor. Say 6 million distinct IPv4 addresses hit a checkout service today. Packed at 4 bytes each, that set is 24 MB before any hash table overhead, and you need one per service, per region, per day you want to compare. Redis answers the same question with a HyperLogLog in about 12 KB per key, at a standard error of about 0.81%.
The thin part is the database around it: a SQLite-shaped file of sketches with time buckets, rollups and a SQL front door (check before you start; this space moves). The version worth building stores nothing but mergeable sketches, grouped by dimension and time bucket, and every aggregate returns its error bound next to the value. You never keep the events. It’s the extreme case of reducing data near the source: keep the answer, drop the rows.
An Evidence Graph Built From Extracted Claims Keeps Contradictions Attached to Their Sources
Feed forty articles about a rumored plant restart to a summarizer and you get one smooth paragraph: several outlets report that production will resume in March, though the ministry has pushed back. It reads well. It also throws away what you’d need to act on it. You can’t tell which outlets reported it, whether each had its own source or all copied one wire story, or what the ministry actually said, a denial or a polite refusal to comment.
DuckDB Already Queries Every File in a Folder, So Build the Part That Infers the Joins
Someone hands you a zip: customers.csv from the CRM, a JSON dump from the billing API, and a SQLite file from an internal app nobody has touched in two years. DuckDB will make all three queryable in a few lines of SQL, with no import step (SELECT * FROM 'customers.csv' works as written). Then you spend the afternoon working out which column joins to which. The CRM says customer_id and stores 00123. The billing API says customerId and stores 123. The SQLite table has a column called customer holding the text 123. Same customer, three spellings.
Facts Should Expire: A Database That Tells an AI Agent When Its Knowledge Has Gone Stale
An agent keeps a memory table, and two rows matter for today’s task: a supplier’s headquarters city, written eleven months ago, and a freight quote, written three hours ago. A SELECT returns both in the same shape. The headquarters is probably still right. The quote may already be wrong. Nothing in either row says so, and the agent repeats both in the same flat tone.
A row has no idea how old its truth is. It might carry a created_at, and a careful person can compute an age from it, but the decay rate belongs to the kind of fact, not to the table. A three-week-old headquarters address is fine. A three-week-old shipping rate is fiction. Server health goes bad in half a minute. No timestamp column holds that knowledge, and nothing forces a query to read it anyway.
Incremental View Maintenance Small Enough to Embed Turns Dashboard Queries Into Lookups
A dashboard tile shows today’s US traffic, so every page load runs SELECT count(*) FROM events WHERE country = 'US' over a table that grew by a few hundred thousand rows since yesterday. SQLite answers correctly. It also walks every matching index entry to do it, because its b-trees don’t keep counts, and it does the same walk for the next viewer and the one after. Between two page loads the answer moves by a handful of rows, yet each load pays for all of them.
Kafka for One Machine: An Embedded Event Log With Offsets, Compaction and No Broker
A desktop app wants an undo history that survives a crash. An edge gateway buffers sensor readings while its uplink is down and has to replay them, in order, once the link is back. An AI agent writes down every action it takes so a bad run can be replayed later. All three are the same data structure: an append-only sequence of records, plus readers that remember where they stopped. Kafka is that structure, and also a cluster, partitions and the people who tune them.
Tag: databases
Counterfactual Store: A Database That Stores Alternatives, Not Just Facts
One direction that feels genuinely different from the earlier list of 20 primitives is a Counterfactual Store. Adjacent ideas certainly exist. Provenance databases, event sourcing, probabilistic databases, simulation systems and version control all touch pieces of it. But as a deliberately tiny infrastructure primitive, there’s no established category built around this exact abstraction.
Normal databases answer “what is true?” Temporal databases, and Temporal KV, add “what was true?” A Counterfactual Store adds a third basic question: what would be true if X were different?
Temporal KV: A Key-Value Store That Remembers History
Temporal KV is a key-value database where a key doesn’t just have a current value. The database automatically remembers how that value changed over time.
In an ordinary KV store, you might write price = 100, then later price = 110, then price = 125. Ask for price and you get 125. The earlier values have normally been overwritten. In a Temporal KV store, all three states stay logically accessible. You can ask for the current value and get 125, or ask “what was price at 10:00 yesterday?” and get 100. The basic abstraction stops being key → value. It becomes key + time → value.
A Database Where Every Value Remembers Its Source, Confidence and Extraction Time
Somebody pastes a population figure into a shared spreadsheet: 1,234,567. It might have come from a census table, a Wikipedia infobox, a city press release or a model’s summary of one of those, and three weeks later nobody can say which. The paste kept the digits. Everything that made them believable stayed in a browser tab that closed long ago.
A value without provenance is a rumor with a data type.
A Feature Store Small Enough to Embed: Point-in-Time Reads for Local and Edge ML
A churn model looks excellent in the notebook and mediocre in production. The model isn’t broken. The training table computed orders_7d with a rolling window over the full history, so some rows counted orders placed after the label date. The serving code, written later in another language, counts a calendar week instead of seven days. One feature, two definitions, and a quiet look into the future. Those are the two bugs a feature store exists to prevent: training-serving skew and label leakage.
A Schema Diff That Warns Which Migration Will Lock a 40-Million-Row Table or Lose Data
The diff in the pull request is one line: ALTER TABLE orders ALTER COLUMN total TYPE bigint;. It reads like a rounding fix, so the reviewer approves it, and the SQL is correct. On a table with 41 million rows it’s also a full rewrite under a lock that stops every read and write until it finishes. A diff shows what changes, never what the change costs.
A schema diff worth using would print consequences instead of SQL, in sentences like “this rewrites a 41-million-row table and blocks every read and write” or “the rollback is impossible without a backup”. Those sentences depend on three things: the statement, the engine and its version, and the size of the table it lands on. With all three you can post a risk report on every migration pull request. With only the first you have a linter.
A Telemetry Database That Forgets on Purpose Keeps Rollups and Anomalies Instead of Raw Rows
At 300 requests a second, one latency metric adds about 26 million rows a day. Nobody will read most of them again. What people ask for a month later is the p99 per route for last Tuesday, and the one request that took nine seconds. A rule that deletes rows after 30 days throws away both answers. Keeping every row forever pays storage bills for data nobody reads.
The telemetry store worth building decides at write time what has to survive. It folds everything else into coarser buckets on a schedule and keeps the few raw events that carry information, whole. Forgetting becomes part of the schema, declared in a policy, instead of a cron job that deletes by age. This is the argument for reducing data near the source, applied to time series.
A Tiny SQL Engine for JSON Streams Fits Between jq and a Stream Processing Cluster
Your service writes one JSON object per line to stdout, and you want the average cpu for host web-3 over the last five minutes. jq can’t answer that, because it forgets each object once it has printed it and has no idea what “five minutes” means. You can fake both with jq -n 'reduce inputs as $e (...)' plus a timestamp comparison, and you’ll have a script nobody wants to touch twice. DuckDB answers the question in one line, but only against a file as it exists right now. ksqlDB, Materialize, RisingWave, Arroyo and Flink SQL answer it continuously, once you’ve deployed a service and agreed to operate it.
An Embedded Sketch Database: Billions of Events, Megabytes of Storage, Error Bars on Every Answer
Counting unique visitors exactly means remembering every visitor. Say 6 million distinct IPv4 addresses hit a checkout service today. Packed at 4 bytes each, that set is 24 MB before any hash table overhead, and you need one per service, per region, per day you want to compare. Redis answers the same question with a HyperLogLog in about 12 KB per key, at a standard error of about 0.81%.
The thin part is the database around it: a SQLite-shaped file of sketches with time buckets, rollups and a SQL front door (check before you start; this space moves). The version worth building stores nothing but mergeable sketches, grouped by dimension and time bucket, and every aggregate returns its error bound next to the value. You never keep the events. It’s the extreme case of reducing data near the source: keep the answer, drop the rows.
Context Window Management as a Database: Ask for 12,000 Tokens, Get the Most Useful Ones
An agent is ninety tool calls into a refactor. Step 12 was a grep that returned 52 KB, and all of it is still in the prompt. The user’s instruction from step 1, “never touch db/migrations”, fell out of the window ten steps ago, because the framework drops the oldest messages first. The agent edits a migration. Nothing malfunctioned; the truncation rule did exactly what it was written to do.
Database-to-Database Sync for Local-First Apps Lives or Dies on Conflict Rules
Take a field technician who edits a work order on a tablet in a basement with no signal. Upstairs, the office edits the same order from a desk. Both hit save at 10:42 by their own clocks, and one of those clocks is ninety seconds off. When the tablet finds a signal, the sync layer has to produce one order that both people can live with. That decision is the product. Offline-first apps are harder than they look, and a large share of the difficulty sits in this one step.
DuckDB Already Queries Every File in a Folder, So Build the Part That Infers the Joins
Someone hands you a zip: customers.csv from the CRM, a JSON dump from the billing API, and a SQLite file from an internal app nobody has touched in two years. DuckDB will make all three queryable in a few lines of SQL, with no import step (SELECT * FROM 'customers.csv' works as written). Then you spend the afternoon working out which column joins to which. The CRM says customer_id and stores 00123. The billing API says customerId and stores 123. The SQLite table has a column called customer holding the text 123. Same customer, three spellings.
Embedded Vector Search Is Crowded: What a One-File Vector Database Needs to Stand Out
You have 40,000 support articles and an app that should offer “similar articles”. Embedded at 768 dimensions in float32, that’s 40,000 × 768 × 4 bytes, about 123 MB of vectors. The standard advice is to stand up a vector database: a service, a port, credentials, a client library and a backup story for 123 MB. A file would do.
Below a few million vectors the server is the overhead, which is why the embedded field filled up fast. So the useful question is what a newcomer brings that the free libraries don’t. My answer is one sharp edge you can state in a sentence, plus measurements the others leave you to make yourself.
Facts Should Expire: A Database That Tells an AI Agent When Its Knowledge Has Gone Stale
An agent keeps a memory table, and two rows matter for today’s task: a supplier’s headquarters city, written eleven months ago, and a freight quote, written three hours ago. A SELECT returns both in the same shape. The headquarters is probably still right. The quote may already be wrong. Nothing in either row says so, and the agent repeats both in the same flat tone.
A row has no idea how old its truth is. It might carry a created_at, and a careful person can compute an age from it, but the decay rate belongs to the kind of fact, not to the table. A three-week-old headquarters address is fine. A three-week-old shipping rate is fiction. Server health goes bad in half a minute. No timestamp column holds that knowledge, and nothing forces a query to read it anyway.
Give Every Database Query a Budget and Fail the Build When It Scans Too Much
A developer changes a login lookup to WHERE lower(email) = lower($1) so that sign-in stops being case-sensitive. Every test passes. The btree index on email can’t serve a query that wraps the column in a function, so Postgres reads the whole users table, and on a test database with forty rows that’s the cheapest plan anyway. The change ships. A week later someone notices login latency tracking the signup count. The fix is a one-line expression index that would have taken a minute if anything had objected during review.
Incremental View Maintenance Small Enough to Embed Turns Dashboard Queries Into Lookups
A dashboard tile shows today’s US traffic, so every page load runs SELECT count(*) FROM events WHERE country = 'US' over a table that grew by a few hundred thousand rows since yesterday. SQLite answers correctly. It also walks every matching index entry to do it, because its b-trees don’t keep counts, and it does the same walk for the next viewer and the one after. Between two page loads the answer moves by a handful of rows, yet each load pays for all of them.
Redis Semantics Without Redis: An Embedded State Engine for Counters, Leases and TTLs
A command-line tool should run only one copy of its nightly export at a time. A small web app wants to cap each user at 60 requests a minute. A desktop app needs to remember when it last synced. All three are state: an integer, a timestamp, an owner. All three usually get solved by adding Redis, because Redis has the verbs for them: INCR, SET NX PX, EXPIRE. The app needed the verbs and got a server along with them, a port and a persistence config included.
Spreadsheet Recalculation Inside a Database: Derived Values That Track Their Own Dependencies
A line item’s quantity goes from 4 to 5. The order subtotal should change, and so should the tax, the order total, the customer’s lifetime value and the regional revenue figure on a dashboard. Which of those actually update depends on which code path made the edit, because each one gets recomputed somewhere different: the checkout handler, the invoice renderer, a nightly job, a SQL view somebody wrote for finance. Every copy of the formula is another chance for two screens to disagree.
SQL and Key-Value Over the Same Bytes: An Old Database Idea Worth Making Small
A sensor node writes a reading every few seconds. The firmware wants one thing from storage: put a record by key, get it back by key, as fast as the flash allows. The dashboard on the gateway wants something else, like average temperature by sensor by hour, joined to a table of sites. The usual answer is two databases with a translation job between them, a key-value store on the device and SQLite or Postgres upstream. Then comes a year of debugging the translation: a unit that changed, a row that arrived twice, a field the device encodes one way and the gateway reads another.
Store Changes Instead of Current Rows: An Embedded Database Built Around History
A support ticket asks two plain questions: which plan was customer 4411 on when the August invoice went out, and who moved them off it? The customers table can’t answer either. It holds today’s row. The audit table someone added two years ago holds most of the story, apart from the week a data fix ran a bulk UPDATE in raw SQL and skipped the ORM callbacks that write the audit rows.
Verified Absence Is Evidence: A Database for Recording That You Checked and Nothing Was There
An auditor asks you to show that customer 1187 was screened against a sanctions list on March 3. The screening job writes a row when it finds a match, and customer 1187 has no rows. That fits two histories: the job ran and found nothing, or the job never ran. The database can’t tell them apart, so you hold no evidence either way.
This is the closed-world assumption doing what SQL has always done: a row that doesn’t exist is false. RDF and OWL went the other way with an open-world assumption, where a missing statement means unknown. Neither has a place for the sentence you actually want to store: I looked here, in this way, at this time, and found nothing.
AltSql: Gives IoT Devices a 15 KB Database That Keeps Working When the Link Drops
Anyone who has built the software side of a connected product knows the integration job. The device keeps its readings and settings in one format and the gateway or cloud service wants those same values as rows in a SQL database. Somebody writes a converter. Then somebody has to keep that converter alive for as long as the device stays in the field, which for industrial equipment or embedded systems can easily be ten years. The converter has to handle offline periods, retries, out-of-order updates, and the device’s own data format changing over time.
Precomputing: Keeps Dashboard Answers Ready in a SQLite File as the Data Arrives
Most dashboards ask the same few questions all day long: requests per endpoint, month-to-date usage for one customer, error rates by status code. The usual setup recounts raw rows from scratch on every refresh, or ships every row to a hosted analytics service that bills by the gigabyte. A dashboard that needs to answer quickly on demand either waits for a database query to finish, or pays for a service that stores everything.
Tag: debugging
Debug From a Timeline of State Changes Instead of Ten Thousand Log Lines
A ticket comes in: order 8812 shows as cancelled, but the customer’s card was charged. You open log search. The checkout service wrote a couple of hundred lines for that request; the payment webhook handler wrote a few dozen; the job that expires unpaid orders wrote a line for every order it looked at that minute. The answer is in there somewhere. Forty minutes later you find it. The expiry job cancelled the order thirty seconds after checkout began, and the payment provider’s webhook landed half a second after that.
Group Errors by Behavioral Signature Instead of Stack Trace Text
Add six lines to the top of a file and ship it. Every stack trace through that file now carries different line numbers, so a tracker that hashes the trace files a bug it has seen a hundred times as a brand-new issue. Meanwhile an older issue titled TimeoutError has collected comments from people who each fixed a different timeout and wondered why it never closed.
Grouping fails in both directions at once. One bug turns into hundreds of issues because the message embeds an order ID, the line numbers moved, or a framework upgrade changed the frames in the middle. Two bugs turn into one because every timeout in the codebase raises the same exception type from the same retry helper.
Tag: developer tools
A Schema Diff That Warns Which Migration Will Lock a 40-Million-Row Table or Lose Data
The diff in the pull request is one line: ALTER TABLE orders ALTER COLUMN total TYPE bigint;. It reads like a rounding fix, so the reviewer approves it, and the SQL is correct. On a table with 41 million rows it’s also a full rewrite under a lock that stops every read and write until it finishes. A diff shows what changes, never what the change costs.
A schema diff worth using would print consequences instead of SQL, in sentences like “this rewrites a 41-million-row table and blocks every read and write” or “the rollback is impossible without a backup”. Those sentences depend on three things: the statement, the engine and its version, and the size of the table it lands on. With all three you can post a risk report on every migration pull request. With only the first you have a linter.
A Single-File Log Database: Pipe Logs In, Query Them With SQL, Hand the File to Anyone
The incident is over, the postmortem is Thursday, and someone wants the logs from the bad three hours. You can attach a gzip nobody will open, paste a screenshot of a grep, or stand up a search cluster to answer one question. The question is usually “which paths returned 500, and when did it start”, which has a GROUP BY hiding in it, and a GROUP BY is where grep runs out. A full observability stack answers it, but that’s a heavy answer for a team that doesn’t already run one.
A Tiny SQL Engine for JSON Streams Fits Between jq and a Stream Processing Cluster
Your service writes one JSON object per line to stdout, and you want the average cpu for host web-3 over the last five minutes. jq can’t answer that, because it forgets each object once it has printed it and has no idea what “five minutes” means. You can fake both with jq -n 'reduce inputs as $e (...)' plus a timestamp comparison, and you’ll have a script nobody wants to touch twice. DuckDB answers the question in one line, but only against a file as it exists right now. ksqlDB, Materialize, RisingWave, Arroyo and Flink SQL answer it continuously, once you’ve deployed a service and agreed to operate it.
Configuration Drift Lives Between Files, So Lint Env Files, YAML, TOML and CI Together
.env.example says DATABASE_URL=postgres://localhost:5432/app. The compose file the team uses for local work mounts a volume and sets DATABASE_URL=sqlite:///data/app.db. The CI workflow exports DB_URL, a name the code stopped reading two refactors ago. Production has a secret called DATABASE_URL that nobody has looked at since the last rotation. Each of those files is valid, and every linter you could point at them passes them. The app still behaves differently on three machines, and the first person to find out is whoever is on call.
Debug From a Timeline of State Changes Instead of Ten Thousand Log Lines
A ticket comes in: order 8812 shows as cancelled, but the customer’s card was charged. You open log search. The checkout service wrote a couple of hundred lines for that request; the payment webhook handler wrote a few dozen; the job that expires unpaid orders wrote a line for every order it looked at that minute. The answer is in there somewhere. Forty minutes later you find it. The expiry job cancelled the order thirty seconds after checkout began, and the payment provider’s webhook landed half a second after that.
DuckDB Already Queries Every File in a Folder, So Build the Part That Infers the Joins
Someone hands you a zip: customers.csv from the CRM, a JSON dump from the billing API, and a SQLite file from an internal app nobody has touched in two years. DuckDB will make all three queryable in a few lines of SQL, with no import step (SELECT * FROM 'customers.csv' works as written). Then you spend the afternoon working out which column joins to which. The CRM says customer_id and stores 00123. The billing API says customerId and stores 123. The SQLite table has a column called customer holding the text 123. Same customer, three spellings.
Group Errors by Behavioral Signature Instead of Stack Trace Text
Add six lines to the top of a file and ship it. Every stack trace through that file now carries different line numbers, so a tracker that hashes the trace files a bug it has seen a hundred times as a brand-new issue. Meanwhile an older issue titled TimeoutError has collected comments from people who each fixed a different timeout and wondered why it never closed.
Grouping fails in both directions at once. One bug turns into hundreds of issues because the message embeds an order ID, the line numbers moved, or a framework upgrade changed the frames in the middle. Two bugs turn into one because every timeout in the codebase raises the same exception type from the same retry helper.
Mapping Every Dependency to the Features That Break If It Disappears Tomorrow
Run npm ls --all on a mid-sized web app and you get a tree that scrolls for pages. It’s accurate and complete, and on the morning a maintainer deletes a package it tells you almost nothing. You can see that tiny-util sits three levels down. You can’t see whether losing it breaks the checkout page or a script nobody has run since spring.
A dependency tree answers “what do I depend on”. The question that matters is “what breaks, and for whom, if this package vanishes or turns hostile”. They need different data. The tree comes from a lockfile. The answer comes from your own source: which functions call the package, which routes, commands and jobs those functions serve, and how much code would change to replace it. A tool that produced that for every package would turn dependency management from an inventory into something a product owner can read.
Most Log Volume Is a Few Templates Repeated, So Reduce Logs Locally Before Shipping Them
Take a day of production logs from one service, mask the numbers, IDs and quoted strings in every line, and sort the resulting patterns by how often they occur. The top of that list is short and dull: health checks, cache hits, a retry notice from a client library nobody owns. Each of those lines was serialized, shipped, parsed and indexed millions of times to say the same thing, and you paid for every copy. Run it on your own logs. The claim is easy to check, so don’t take it on faith.
One Binary, One File, No Daemon: The SQLite and nginx Pattern as a Product Strategy
Compare two quickstarts. The first says to install Docker, bring up a compose file with a database, a cache and a worker, create an account, and paste a token into an env file. The second says to download one file and run it. Both tools might solve the same problem. Only one of them survives an evaluation that lasts ten minutes.
The second quickstart is a product decision, made in the architecture. SQLite and nginx made it decades ago, and Caddy, DuckDB, ripgrep, jq and Hugo have made it again in their own corners. Small surface area, few dependencies and one artifact to copy work as an adoption strategy. For a one-person or AI-assisted project they also work as the only scope control that holds up. That’s the claim, and the rest of this post tries to break it.
Preconfiguration: Writes Coding Agent Setup Files From One Spec and Tests Them on a Clean Machine
Cloud coding agents start each task on a fresh machine. Before the agent can run a single test, something has to install the right runtime, start a database, configure environment variables, and download dependencies. Every platform that runs agents wants those instructions in its own file: Copilot expects a setup workflow, Cursor builds a Dockerfile, other platforms want shell scripts or configuration in other formats. A team that uses two or three agents writes the same setup two or three times, and mistakes usually show up later as an agent session that stalls because a database port wasn’t open or a runtime was the wrong version.
Nine Apps Worth Coding, and the Hard Part Buried in Each One
Every app idea has a boring 90% and a nasty 10%. The boring part is CRUD, auth, a settings page, Stripe. The nasty part is the one subsystem that decides whether the thing works at all, and it’s usually not the part that looks hard in the pitch. Below are nine builds worth attempting, with the nasty 10% named up front so you can decide whether you want to spend your weekends there.
AI App Builders Reviewed: Lovable, Base44, Bolt, Replit and v0 Compared
Every one of these platforms will take a sentence and hand you a running application. That part is settled, and it works. What separates them is everything that happens afterwards: what the bill looks like in month three, whether you can take the code somewhere else, and whether the app is open to the internet by default.
They also get lumped into one category when they belong in three. Hosted prompt-to-app builders (Lovable, Base44, Bolt, Replit) generate and host the whole thing. UI-first generators like v0 hand you code and leave hosting to you. Editor and terminal agents such as Cursor and Claude Code sit inside a real repository and assume you can read the output. Security researchers draw the line in the same place, and for a reason: the editor tools require a human to review code before it ships, while the builders generate, execute and deploy with almost no oversight in between.
Cloudflare Kitesurf: An Agent-First Browser That Uses 3-7x Less Memory Than Chromium
Cloudflare shipped Kitesurf on August 6, a web browser it wrote from scratch for AI agents. It runs entirely inside Workers. No Chromium underneath, no container, no headless Chrome process idling in a warm pool waiting for something to do.
The problem it targets is a billing problem. Agents need browsers to do real work, and Chromium is the only serious option, but Chromium was built for a person sitting in front of a screen. Tabs, extensions, device sync, sixty frames a second of smooth scrolling. An agent does not care about any of that. What it cares about is token count, context window, and what the session costs. Handing every agent its own Chromium instance prices most agentic applications out of the web entirely, and leaves browsing to the expensive models that can afford it.
Vibe Coding Works Until You Have to Read the Code
Vibe coding is fine for code you’re going to throw away, and most of the fighting about it is really people disagreeing about which code that is.
Last month I needed a script to pull a CSV off a shared drive, reshape three columns, and push the rows into an API. I described it, ran what came back, fixed one wrong column name, and never read the rest. It worked. It ran twice and I deleted it. Reading that code line by line would have cost me an afternoon and bought me nothing.
DigitalOcean Launches AI-Native Cloud at Deploy 2026
DigitalOcean has announced the DigitalOcean AI-Native Cloud, positioning itself as the first cloud platform built end-to-end for the inference and agentic era. The launch took place at Deploy 2026, the company’s annual conference for builders, and the platform is available to customers today.
The Problem It’s Solving
AI developers have long been squeezed between two imperfect options: hyperscalers like AWS with enterprise-grade complexity and unpredictable costs, or newer GPU clouds that hand you bare metal and tokens but leave you to wire everything else together yourself. DigitalOcean is pitching its AI-Native Cloud as the third path — a fully integrated stack that handles infrastructure through agents, without the assembly tax.
Tag: devops
Configuration Drift Lives Between Files, So Lint Env Files, YAML, TOML and CI Together
.env.example says DATABASE_URL=postgres://localhost:5432/app. The compose file the team uses for local work mounts a volume and sets DATABASE_URL=sqlite:///data/app.db. The CI workflow exports DB_URL, a name the code stopped reading two refactors ago. Production has a secret called DATABASE_URL that nobody has looked at since the last rotation. Each of those files is valid, and every linter you could point at them passes them. The app still behaves differently on three machines, and the first person to find out is whoever is on call.
Cron for AI Agents: Schedules, Timeouts, Overlap Rules and Cost Ceilings in One Config File
A nightly agent job triages new issues. One night an issue arrives with a 400 KB log attached. The agent reads it, a tool call fails, the agent retries, and the loop runs until the month’s token budget is gone. Meanwhile cron, which has no idea what a token is, starts the next run on schedule. Now two copies are fighting over the same issue tracker.
Cron was built for jobs that cost nothing, finish in seconds and do the same thing every time. Agent jobs cost money per token, run for an unpredictable time and can loop. The useful ones are still boring and periodic: summarize what changed in a repo since yesterday, triage new issues each morning, check a competitor’s pricing page weekly. What they need is a scheduler that stays as small as cron and adds four things: a cost ceiling, a timeout that actually kills, an overlap rule, and state carried between runs. Anything past that is an orchestration platform, a different and much larger product.
Cloudflare Worker Previews Setup: Which Bindings Isolate Per Branch and Which You Configure Yourself
Cloudflare shipped Worker Previews today, and the headline is easy to state. Every git branch gets its own running Worker, with its own URL, its own config, its own logs, its own traces. You run npx wrangler preview, and the branch you’re sitting on becomes something you can open in a browser and click through. Cloudflare says you can run hundreds of them side by side without them touching each other or production.
Testing Mobile Apps at Scale Without Losing Your Mind
Mobile testing is harder than web testing for reasons that are partly technical and partly organizational. The technical reasons: the diversity of physical devices, OS versions, screen sizes, and hardware configurations that a production mobile app must run on is several orders of magnitude larger than the browser matrix that web applications face. The organizational reasons: mobile development cycles historically moved faster than testing infrastructure could keep pace with, producing teams that ship without adequate test coverage and accumulate testing debt that compounds with each release.
Tag: embedded databases
40 Projects Worth Building: SQLite for X, Tiny Infrastructure, MCP Tools and Edge Systems
The most promising territory for a small team isn’t another large framework. It’s the opposite: infrastructure software you can explain in one sentence, ship as one binary or embed as one library, run with almost no operational burden, and that solves one irritating problem unusually well. SQLite and nginx are the right mental models because their appeal is architectural, not just functional: small surface area, predictable behavior, few dependencies, easy deployment, and usefulness far beyond the original use case. (More on that in the SQLite and nginx pattern as a product strategy.)
A Background Job Queue in One SQLite File Covers What Most Apps Deploy Redis For
A signup handler has to send a welcome email, and sending it inline puts a third-party API call inside your request. So you move it into a background job, and the usual next step is Redis, a client library, a worker process, a dashboard, and a note in the deploy docs about what happens to queued jobs when Redis restarts without persistence. If the app runs on one machine, you’ve added a second stateful service to look after a table’s worth of data.
A Feature Store Small Enough to Embed: Point-in-Time Reads for Local and Edge ML
A churn model looks excellent in the notebook and mediocre in production. The model isn’t broken. The training table computed orders_7d with a rolling window over the full history, so some rows counted orders placed after the label date. The serving code, written later in another language, counts a calendar week instead of seven days. One feature, two definitions, and a quiet look into the future. Those are the two bugs a feature store exists to prevent: training-serving skew and label leakage.
Embedded Vector Search Is Crowded: What a One-File Vector Database Needs to Stand Out
You have 40,000 support articles and an app that should offer “similar articles”. Embedded at 768 dimensions in float32, that’s 40,000 × 768 × 4 bytes, about 123 MB of vectors. The standard advice is to stand up a vector database: a service, a port, credentials, a client library and a backup story for 123 MB. A file would do.
Below a few million vectors the server is the overhead, which is why the embedded field filled up fast. So the useful question is what a newcomer brings that the free libraries don’t. My answer is one sharp edge you can state in a sentence, plus measurements the others leave you to make yourself.
Kafka for One Machine: An Embedded Event Log With Offsets, Compaction and No Broker
A desktop app wants an undo history that survives a crash. An edge gateway buffers sensor readings while its uplink is down and has to replay them, in order, once the link is back. An AI agent writes down every action it takes so a bad run can be replayed later. All three are the same data structure: an append-only sequence of records, plus readers that remember where they stopped. Kafka is that structure, and also a cluster, partitions and the people who tune them.
Redis Semantics Without Redis: An Embedded State Engine for Counters, Leases and TTLs
A command-line tool should run only one copy of its nightly export at a time. A small web app wants to cap each user at 60 requests a minute. A desktop app needs to remember when it last synced. All three are state: an integer, a timestamp, an owner. All three usually get solved by adding Redis, because Redis has the verbs for them: INCR, SET NX PX, EXPIRE. The app needed the verbs and got a server along with them, a port and a persistence config included.
SQL and Key-Value Over the Same Bytes: An Old Database Idea Worth Making Small
A sensor node writes a reading every few seconds. The firmware wants one thing from storage: put a record by key, get it back by key, as fast as the flash allows. The dashboard on the gateway wants something else, like average temperature by sensor by hour, joined to a table of sites. The usual answer is two databases with a translation job between them, a key-value store on the device and SQLite or Postgres upstream. Then comes a year of debugging the translation: a unit that changed, a row that arrived twice, a field the device encodes one way and the gateway reads another.
Store Changes Instead of Current Rows: An Embedded Database Built Around History
A support ticket asks two plain questions: which plan was customer 4411 on when the August invoice went out, and who moved them off it? The customers table can’t answer either. It holds today’s row. The audit table someone added two years ago holds most of the story, apart from the week a data fix ran a bulk UPDATE in raw SQL and skipped the ORM callbacks that write the audit rows.
AltSql: Gives IoT Devices a 15 KB Database That Keeps Working When the Link Drops
Anyone who has built the software side of a connected product knows the integration job. The device keeps its readings and settings in one format and the gateway or cloud service wants those same values as rows in a SQL database. Somebody writes a converter. Then somebody has to keep that converter alive for as long as the device stays in the field, which for industrial equipment or embedded systems can easily be ten years. The converter has to handle offline periods, retries, out-of-order updates, and the device’s own data format changing over time.
Tag: flutter
Cross-Platform vs Native: The Honest Assessment Nobody Gives You
The cross-platform vs native debate has a quality problem: the people most qualified to give objective assessments have financial or professional stakes in one answer. Agency developers who charge by the hour prefer native because it doubles the billable work. Cross-platform framework vendors publish benchmark comparisons designed to minimize the gaps between their output and native. Native platform advocates at Apple and Google have obvious incentives to characterize cross-platform output as inferior.
Flutter's Bet on a Single Codebase Has Mostly Paid Off
Google’s decision to build Flutter on top of Dart — a language that had minimal developer mindshare and an uncertain future when Flutter launched — was a risk that the broader developer community viewed with skepticism. Dart was not JavaScript. It was not Kotlin. It was not a language that developers had strong feelings about because most developers had never used it. Building a cross-platform UI framework on an obscure language was, on its face, an unusual strategic choice.
Tag: game development
PixVerse Closes Series C Extension at $439 Million and Pivots From AI Video Into Games
PixVerse has closed an extension to its Series C, bringing total fundraising in the round to $439 million, and used the announcement to signal a strategic move well beyond the AI video generation market it built its name in. The Singapore-based company is extending its platform into games and interactive entertainment.
The extension pulled in a notably broad investor set. New participants include Alibaba, Lollapalooza Capital, Ivy Capital, Grand Mount Capital, Eastern Bell Capital, Mirae Asset, BlueFocus, and CloudAlpha, alongside returning investors iGlobe Partners and OCBC’s LionX Ventures. The mix of Chinese strategic capital, Korean institutional money, and Singaporean bank-backed venture funding says something about where the AI media stack is being financed — and it is not exclusively in California.
Tag: go
20 Primitive Project Ideas: Tiny Go Engines That Do the Essential 10% of Redis, Kafka and Etcd
Given the direction of AltSql, BareProxy, Precomputing and the VPN primitives work, there is still a surprisingly large design space for projects that are smaller than platforms but more fundamental than ordinary applications. The best candidates have a very simple sentence behind them: “X currently requires a framework, service or stack; this does the essential 10% in one tiny binary, library or file.”
Look for primitives that can begin as a credible 2,000–10,000-line Go project, have an immediately understandable demo, and later sit underneath commercial products rather than needing to become a SaaS business immediately. Here are twenty directions that fit that model.
BareProxy: A Small Go Web Server and Reverse Proxy That Explains Every Routing Decision
Most sites run a thin slice of nginx in front of their application: TLS termination, serving static files from a folder, a couple of routes to a backend service, health checks, and the occasional reload. The configuration grows anyway, one regular expression at a time, until nobody is quite sure which block handles a given URL, and a change that looks safe to one person breaks something in production that another person didn’t know existed.
Tag: indie development
One Binary, One File, No Daemon: The SQLite and nginx Pattern as a Product Strategy
Compare two quickstarts. The first says to install Docker, bring up a compose file with a database, a cache and a worker, create an account, and paste a token into an env file. The second says to download one file and run it. Both tools might solve the same problem. Only one of them survives an evaluation that lasts ten minutes.
The second quickstart is a product decision, made in the architecture. SQLite and nginx made it decades ago, and Caddy, DuckDB, ripgrep, jq and Hugo have made it again in their own corners. Small surface area, few dependencies and one artifact to copy work as an adoption strategy. For a one-person or AI-assisted project they also work as the only scope control that holds up. That’s the claim, and the rest of this post tries to break it.
Screening App Ideas Before You Write Code: Four Questions, Starting With Who Pays
App ideas cost nothing. Every one of them looks shippable in a weekend, and then the weekend turns into three months of auth flows, sync bugs, review notes and a paywall that took longer than the app.
So before Xcode or Android Studio opens, put the idea through four questions and write the answers down. Who pays? What problem does it solve? Can you say what it does in one sentence? Why would anyone switch, and what stops Apple from copying it? Ask them in that order. Money goes first because it kills weak ideas fastest, while a kill still costs an evening.
Verdent Updates AI Platform to Function as a Full Engineering Team for Solo Builders
Verdent has updated its AI-native software platform to operate across the full build cycle — planning, execution, validation, and delivery — rather than stopping at code generation. The update positions Verdent less as a coding assistant and more as a substitute for an engineering team, handling the sequence of decisions and handoffs that typically require multiple people to coordinate.
The gap between a software idea and a shipped product is not usually an ideas problem. It is a labor and coordination problem. Crossing it has historically required hiring engineers, managing sprints, and absorbing the context loss that comes with every handoff. Verdent’s design premise is that AI can now carry that load end-to-end: breaking a goal into tasks, selecting appropriate tooling, writing and testing code, and continuing work asynchronously through Slack or Telegram integrations even when the user is away. Context is retained across sessions, including stack decisions, prior build choices, and current state, so work does not reset between conversations.
The Side Project App Is Not Dead. The Side Project App Business Is.
The romantic narrative of the solo developer who builds an app in nights and weekends, publishes it to the App Store, and generates meaningful income from passive sales is not entirely false. It is sufficiently true in enough specific cases to sustain the mythology and sufficiently rare to make the mythology dangerous as a planning assumption.
The structural conditions that made the App Store a viable path to meaningful passive income for individual developers in 2010 to 2015 have changed. The App Store had fewer apps. Discovery was less competitive. Users were more willing to pay upfront for apps they had not tried. The apps that met a basic need in a well-executed way could find their audience without significant marketing investment.
Tag: infrastructure
20 Primitive Project Ideas: Tiny Go Engines That Do the Essential 10% of Redis, Kafka and Etcd
Given the direction of AltSql, BareProxy, Precomputing and the VPN primitives work, there is still a surprisingly large design space for projects that are smaller than platforms but more fundamental than ordinary applications. The best candidates have a very simple sentence behind them: “X currently requires a framework, service or stack; this does the essential 10% in one tiny binary, library or file.”
Look for primitives that can begin as a credible 2,000–10,000-line Go project, have an immediately understandable demo, and later sit underneath commercial products rather than needing to become a SaaS business immediately. Here are twenty directions that fit that model.
40 Projects Worth Building: SQLite for X, Tiny Infrastructure, MCP Tools and Edge Systems
The most promising territory for a small team isn’t another large framework. It’s the opposite: infrastructure software you can explain in one sentence, ship as one binary or embed as one library, run with almost no operational burden, and that solves one irritating problem unusually well. SQLite and nginx are the right mental models because their appeal is architectural, not just functional: small surface area, predictable behavior, few dependencies, easy deployment, and usefulness far beyond the original use case. (More on that in the SQLite and nginx pattern as a product strategy.)
40 Radically Different Infrastructure Primitives, From Reach and Expect to Ignorance and Stop
This list deliberately leaves “tiny version of Redis, Kafka or SQLite” territory behind. That was the first list of 20 primitives. The more interesting search space is a primitive that introduces a new operation, one developers might eventually feel should have existed all along. Some research paper or niche project has probably explored pieces of these. They’re meant as category-level concepts, not smaller copies of familiar products.
Forty primitives
1. Reach. Store a current state plus transition rules and continuously maintain which states are reachable from here: REACHABLE(current_state). A database answers what is; Reach answers what can happen. Uses: AI agent safety, workflows, infrastructure, manufacturing, cybersecurity attack paths.
Counterfactual Store: A Database That Stores Alternatives, Not Just Facts
One direction that feels genuinely different from the earlier list of 20 primitives is a Counterfactual Store. Adjacent ideas certainly exist. Provenance databases, event sourcing, probabilistic databases, simulation systems and version control all touch pieces of it. But as a deliberately tiny infrastructure primitive, there’s no established category built around this exact abstraction.
Normal databases answer “what is true?” Temporal databases, and Temporal KV, add “what was true?” A Counterfactual Store adds a third basic question: what would be true if X were different?
Screening 20 Infrastructure Primitives Money First: Why Distill and Precomputing Survive
Run the 20 primitive project ideas through the four-question screen strictly and the ranking changes a lot. Several technically attractive ideas turn into weak projects. The economic buyer is unclear, free infrastructure already solves the problem well enough, or the moat amounts to “ours is smaller.”
So Statefile, Lease, BareQueue, TTL, Count, Remember, Freeze and probably ConfigLog go out at this stage. They all solve real engineering problems, but the money question is poor. Redis, SQLite, existing Go libraries, message queues, object storage, Git and cloud infrastructure already give acceptable answers. A tiny implementation might make a respectable GitHub project. “Simpler and smaller” doesn’t tell you who eventually writes a meaningful check.
Temporal KV: A Key-Value Store That Remembers History
Temporal KV is a key-value database where a key doesn’t just have a current value. The database automatically remembers how that value changed over time.
In an ordinary KV store, you might write price = 100, then later price = 110, then price = 125. Ask for price and you get 125. The earlier values have normally been overwritten. In a Temporal KV store, all three states stay logically accessible. You can ask for the current value and get 125, or ask “what was price at 10:00 yesterday?” and get 100. The basic abstraction stops being key → value. It becomes key + time → value.
Tag: ios
Apple's US Link-Out Fee Is Zero Until a Judge Sets It, and Apple Is Asking for Up to 15%
If your iOS app sells anything digital in the US, you can send users to your own web checkout today and Apple takes nothing from that sale. That has been true since the contempt ruling in Epic v. Apple in April 2025, and it still holds while a court works out what Apple may charge instead. Apple’s opening bid is 15%. Epic’s answer is close to zero.
For developers the window is open now, and it won’t stay free forever. What you build in the meantime should hold up whichever number the court lands on.
Mobile App Performance: The Five Metrics That Decide Retention and Store Ratings
Performance work in mobile development wastes more effort than almost any other kind of engineering. Teams burn sprints shaving milliseconds off benchmarks that no user will ever feel. Meanwhile the problems that actually make people uninstall, the freezes, the janky feeds, the phone that’s dead by 4pm, sit in the backlog because nobody put a number on them.
The gap between what’s easy to measure and what users care about is wide. Closing it starts with picking the right metrics.
Mobile Accessibility Is the Case Developers Keep Ignoring
The accessibility argument is made with sufficient frequency in developer conferences and engineering blog posts that it has acquired the character of something everyone agrees with and nobody acts on. Apps ship with missing accessibility labels, unlabeled buttons, broken VoiceOver navigation, and dynamic type support that was added for text elements but forgotten for layout constraints. The gap between the accessibility investment that development teams describe as important and the accessibility state of their shipped applications is among the widest in software development.
Testing Mobile Apps at Scale Without Losing Your Mind
Mobile testing is harder than web testing for reasons that are partly technical and partly organizational. The technical reasons: the diversity of physical devices, OS versions, screen sizes, and hardware configurations that a production mobile app must run on is several orders of magnitude larger than the browser matrix that web applications face. The organizational reasons: mobile development cycles historically moved faster than testing infrastructure could keep pace with, producing teams that ship without adequate test coverage and accumulate testing debt that compounds with each release.
App Store Optimization in 2026 Is a Different Game Than It Was
App Store Optimization was, in its early form, a relatively straightforward keyword game. Include the right terms in your app title and description, achieve a certain volume of downloads and ratings, and the app store algorithm would surface your app to relevant searches. The practitioners who figured this out first made significant money. The techniques spread, the competition intensified, and the algorithm changed — as algorithms always do when they are being gamed at scale.
Cross-Platform vs Native: The Honest Assessment Nobody Gives You
The cross-platform vs native debate has a quality problem: the people most qualified to give objective assessments have financial or professional stakes in one answer. Agency developers who charge by the hour prefer native because it doubles the billable work. Cross-platform framework vendors publish benchmark comparisons designed to minimize the gaps between their output and native. Native platform advocates at Apple and Google have obvious incentives to characterize cross-platform output as inferior.
Mobile Security: What Developers Consistently Get Wrong
Mobile security vulnerabilities cluster in a predictable set of categories. The same mistakes appear in security audits of consumer apps, enterprise apps, and fintech apps with equal regularity. The recurrence of the same errors across different teams and different organizations suggests that the failures are not primarily due to ignorance — most mobile developers are aware that security matters — but to a gap between security knowledge and the specific engineering practices that translate that knowledge into secure code.
SwiftUI After Five Years: What Works and What Doesn't
SwiftUI launched in 2019 with a demonstration that made experienced iOS developers simultaneously excited and nervous. Excited because the declarative paradigm promised to eliminate the impedance mismatch between interface builder storyboards and code. Nervous because Apple’s track record with new frameworks included several that were replaced, deprecated, or quietly ignored within a few development cycles.
Five years later, SwiftUI is neither the complete replacement for UIKit that Apple’s marketing implied nor the abandoned experiment that skeptics predicted. It is a mature but still-evolving framework that handles a large majority of common iOS UI requirements elegantly, struggles with a specific set of advanced requirements, and has permanently changed how iOS UI code is written even when developers reach for UIKit to solve problems SwiftUI cannot.
Swift vs Kotlin: The State of Native Mobile Development in 2026
The question of whether to build natively for iOS and Android or to abstract across both platforms with a cross-platform framework has occupied mobile development teams for more than a decade. The answer has not settled. What has settled is the character of native development itself — and in 2026, Swift and Kotlin have each reached a maturity that makes the native argument significantly stronger than it was five years ago.
Tag: iot
A Feature Store Small Enough to Embed: Point-in-Time Reads for Local and Edge ML
A churn model looks excellent in the notebook and mediocre in production. The model isn’t broken. The training table computed orders_7d with a rolling window over the full history, so some rows counted orders placed after the label date. The serving code, written later in another language, counts a calendar week instead of seven days. One feature, two definitions, and a quiet look into the future. Those are the two bugs a feature store exists to prevent: training-serving skew and label leakage.
A Telemetry Database That Forgets on Purpose Keeps Rollups and Anomalies Instead of Raw Rows
At 300 requests a second, one latency metric adds about 26 million rows a day. Nobody will read most of them again. What people ask for a month later is the p99 per route for last Tuesday, and the one request that took nine seconds. A rule that deletes rows after 30 days throws away both answers. Keeping every row forever pays storage bills for data nobody reads.
The telemetry store worth building decides at write time what has to survive. It folds everything else into coarser buckets on a schedule and keeps the few raw events that carry information, whole. Forgetting becomes part of the schema, declared in a policy, instead of a cron job that deletes by age. This is the argument for reducing data near the source, applied to time series.
SQL and Key-Value Over the Same Bytes: An Old Database Idea Worth Making Small
A sensor node writes a reading every few seconds. The firmware wants one thing from storage: put a record by key, get it back by key, as fast as the flash allows. The dashboard on the gateway wants something else, like average temperature by sensor by hour, joined to a table of sites. The usual answer is two databases with a translation job between them, a key-value store on the device and SQLite or Postgres upstream. Then comes a year of debugging the translation: a unit that changed, a row that arrived twice, a field the device encodes one way and the gateway reads another.
AltSql: Gives IoT Devices a 15 KB Database That Keeps Working When the Link Drops
Anyone who has built the software side of a connected product knows the integration job. The device keeps its readings and settings in one format and the gateway or cloud service wants those same values as rows in a SQL database. Somebody writes a converter. Then somebody has to keep that converter alive for as long as the device stays in the field, which for industrial equipment or embedded systems can easily be ten years. The converter has to handle offline periods, retries, out-of-order updates, and the device’s own data format changing over time.
Tag: javascript
State Management in React Native Has Too Many Options and One Right Answer
The React Native state management ecosystem is the most frequently relitigated technical decision in mobile JavaScript development. Every twelve to eighteen months, a new library emerges, accumulates advocates, generates a wave of “why I switched from X to Y” blog posts, and joins the list of options that teams now have to evaluate. The list includes Redux, MobX, Zustand, Jotai, Recoil, TanStack Query, SWR, Context API, and several others with smaller followings. The churn produces the impression that state management is an unsolved problem requiring continuous reinvention.
React Native in 2026: Mature, Imperfect, Indispensable
React Native was announced by Facebook in 2015 with a promise that rewrote the calculus of mobile development: learn once, write anywhere. The promise was qualified from the start — React Native was never write once, run anywhere in the way that early web-based mobile frameworks had claimed to be — but it was credible enough to reshape how a generation of mobile teams made technology decisions.
Eleven years later, React Native is used in production by Microsoft, Shopify, Coinbase, and thousands of smaller organizations. It has survived the emergence of Flutter, the maturation of Kotlin Multiplatform, and a period of internal uncertainty at Meta when the framework’s future was genuinely in question. Its survival reflects something real about the problem it solves and the ecosystem it has built.
Tag: kotlin
Jetpack Compose Is Winning Android UI Development
Google’s transition of Android UI development from the XML layout system to Jetpack Compose has been, by the standards of platform UI framework migrations, unusually smooth. Compose became stable in August 2021. By 2024, it was the recommended approach for new Android development. In 2026, the question for Android teams is no longer whether to adopt Compose but how to manage the migration of existing View-based codebases.
The comparison with SwiftUI is instructive. Both frameworks launched within two years of each other, both represent declarative replacements for older imperative UI systems, and both have faced criticism for gaps between their initial capabilities and the full feature set of what they replaced. Compose has navigated this transition with fewer of the minimum-API-level constraints that limit SwiftUI’s adoption curve, because Android’s broader device compatibility requirements have historically pushed Google toward more conservative backward compatibility policies.
Swift vs Kotlin: The State of Native Mobile Development in 2026
The question of whether to build natively for iOS and Android or to abstract across both platforms with a cross-platform framework has occupied mobile development teams for more than a decade. The answer has not settled. What has settled is the character of native development itself — and in 2026, Swift and Kotlin have each reached a maturity that makes the native argument significantly stronger than it was five years ago.
Tag: mcp
40 Projects Worth Building: SQLite for X, Tiny Infrastructure, MCP Tools and Edge Systems
The most promising territory for a small team isn’t another large framework. It’s the opposite: infrastructure software you can explain in one sentence, ship as one binary or embed as one library, run with almost no operational burden, and that solves one irritating problem unusually well. SQLite and nginx are the right mental models because their appeal is architectural, not just functional: small surface area, predictable behavior, few dependencies, easy deployment, and usefulness far beyond the original use case. (More on that in the SQLite and nginx pattern as a product strategy.)
Tag: mobile development
Mobile App Performance: The Five Metrics That Decide Retention and Store Ratings
Performance work in mobile development wastes more effort than almost any other kind of engineering. Teams burn sprints shaving milliseconds off benchmarks that no user will ever feel. Meanwhile the problems that actually make people uninstall, the freezes, the janky feeds, the phone that’s dead by 4pm, sit in the backlog because nobody put a number on them.
The gap between what’s easy to measure and what users care about is wide. Closing it starts with picking the right metrics.
The App Monetization Landscape Has Changed and Most Teams Have Not Caught Up
Apple’s App Tracking Transparency framework, which required explicit user permission for cross-app tracking, reduced mobile advertising effectiveness in ways the industry understood theoretically in 2021 and has spent the subsequent years quantifying empirically. The quantification has not been favorable. CPMs for iOS advertising inventory dropped significantly in the period following ATT’s rollout. Attribution accuracy — the ability to connect an ad impression to a downstream app install or purchase — declined materially. The precision-targeted mobile advertising ecosystem that had been the dominant growth channel for consumer apps was not destroyed, but it was substantially impaired.
Building Offline-First Mobile Apps Is Harder Than It Looks and Worth It
The default architecture for most mobile applications treats network connectivity as a reliable precondition. API calls are made on demand. Failures produce error states. The user waits for responses. This architecture produces apps that work acceptably on fast, reliable connections and badly on slow, intermittent, or absent connections — which describes the conditions under which many mobile users actually use apps.
Offline-first architecture inverts this assumption. The app reads from and writes to local storage first. Network synchronization happens in the background, opportunistically, whenever connectivity permits. The user experience is fast and available regardless of network state. The complexity is in the synchronization layer, which most teams underestimate significantly before they build it.
Mobile Accessibility Is the Case Developers Keep Ignoring
The accessibility argument is made with sufficient frequency in developer conferences and engineering blog posts that it has acquired the character of something everyone agrees with and nobody acts on. Apps ship with missing accessibility labels, unlabeled buttons, broken VoiceOver navigation, and dynamic type support that was added for text elements but forgotten for layout constraints. The gap between the accessibility investment that development teams describe as important and the accessibility state of their shipped applications is among the widest in software development.
Testing Mobile Apps at Scale Without Losing Your Mind
Mobile testing is harder than web testing for reasons that are partly technical and partly organizational. The technical reasons: the diversity of physical devices, OS versions, screen sizes, and hardware configurations that a production mobile app must run on is several orders of magnitude larger than the browser matrix that web applications face. The organizational reasons: mobile development cycles historically moved faster than testing infrastructure could keep pace with, producing teams that ship without adequate test coverage and accumulate testing debt that compounds with each release.
App Store Optimization in 2026 Is a Different Game Than It Was
App Store Optimization was, in its early form, a relatively straightforward keyword game. Include the right terms in your app title and description, achieve a certain volume of downloads and ratings, and the app store algorithm would surface your app to relevant searches. The practitioners who figured this out first made significant money. The techniques spread, the competition intensified, and the algorithm changed — as algorithms always do when they are being gamed at scale.
Cross-Platform vs Native: The Honest Assessment Nobody Gives You
The cross-platform vs native debate has a quality problem: the people most qualified to give objective assessments have financial or professional stakes in one answer. Agency developers who charge by the hour prefer native because it doubles the billable work. Cross-platform framework vendors publish benchmark comparisons designed to minimize the gaps between their output and native. Native platform advocates at Apple and Google have obvious incentives to characterize cross-platform output as inferior.
AI in Mobile Apps: What Is Working Beyond the Hype
The integration of AI capabilities into mobile applications has followed the familiar hype cycle pattern: an initial period of breathless coverage about what AI would do for apps, followed by a quieter period of teams discovering which AI features users actually value and which are dismissed as gimmicks within the first week of use. The dust has not fully settled, but the outline of what works is becoming clear.
The AI features that have demonstrated durable user value are mostly not the ones that received the most attention during the hype phase. Large language model chatbots embedded in apps — the most visible AI feature of the 2023-2024 period — have retention profiles that most teams find disappointing. Users try them, find them useful or impressive in isolated interactions, and then forget to use them because the chat interface requires more effort than the specific task typically warrants.
Mobile Security: What Developers Consistently Get Wrong
Mobile security vulnerabilities cluster in a predictable set of categories. The same mistakes appear in security audits of consumer apps, enterprise apps, and fintech apps with equal regularity. The recurrence of the same errors across different teams and different organizations suggests that the failures are not primarily due to ignorance — most mobile developers are aware that security matters — but to a gap between security knowledge and the specific engineering practices that translate that knowledge into secure code.
The Subscription Model Reckoning Is Hitting Mobile Apps Hard
The subscription model’s dominance of mobile app monetization was, until recently, treated as a settled question. One-time purchases were dead. Advertising was privacy-constrained and algorithmically contested. Subscriptions provided predictable revenue, lower upfront friction, and the renewal economics that made customer lifetime value calculations favorable. Every growth deck from 2018 to 2022 told the same story about subscriptions being the obvious answer.
The reckoning that followed was predictable to anyone paying attention to the demand side of that story. Users had subscribed to enough things. The subscription fatigue that entertainment services experienced — as the number of streaming subscriptions a household maintained reached and exceeded what they were willing to pay — extended to software. Productivity apps, fitness apps, photo editors, and note-taking tools all compete for a monthly budget that users have become conscious of in ways they were not during the subscription model’s initial adoption phase.
Push Notifications Have a Spam Problem That Developers Built
Push notifications were introduced as a mechanism for delivering timely, relevant information to mobile users. They have become, in the hands of most apps, a mechanism for re-engaging users who have stopped using an app — delivered at volumes and frequencies that have trained users to disable notifications as a reflex rather than a deliberate choice.
The data on notification effectiveness tells a story that most growth teams choose not to hear. Opt-in rates for push notifications have declined steadily as users have learned from experience what push permission grants apps permission to do. iOS’s explicit permission prompt — which apps must request before sending any notification — shows opt-in rates below 50 percent for most app categories. Users who do opt in disable notifications at rates that correlate directly with how many notifications an app sends, not with how relevant those notifications are.
The Mobile Backend Dilemma: Firebase, Supabase, or Build Your Own
Every mobile app that does anything interesting eventually needs a backend. Authentication, data storage, push notifications, file uploads, real-time updates — the list of backend requirements grows quickly once an app moves beyond a local-only experience. The decision of how to provide that backend is one of the most consequential architectural choices a mobile development team makes, and it is one that becomes substantially harder to reverse after significant user data has accumulated.
React Native in 2026: Mature, Imperfect, Indispensable
React Native was announced by Facebook in 2015 with a promise that rewrote the calculus of mobile development: learn once, write anywhere. The promise was qualified from the start — React Native was never write once, run anywhere in the way that early web-based mobile frameworks had claimed to be — but it was credible enough to reshape how a generation of mobile teams made technology decisions.
Eleven years later, React Native is used in production by Microsoft, Shopify, Coinbase, and thousands of smaller organizations. It has survived the emergence of Flutter, the maturation of Kotlin Multiplatform, and a period of internal uncertainty at Meta when the framework’s future was genuinely in question. Its survival reflects something real about the problem it solves and the ecosystem it has built.
Swift vs Kotlin: The State of Native Mobile Development in 2026
The question of whether to build natively for iOS and Android or to abstract across both platforms with a cross-platform framework has occupied mobile development teams for more than a decade. The answer has not settled. What has settled is the character of native development itself — and in 2026, Swift and Kotlin have each reached a maturity that makes the native argument significantly stronger than it was five years ago.
Tag: monetization
Apple's US Link-Out Fee Is Zero Until a Judge Sets It, and Apple Is Asking for Up to 15%
If your iOS app sells anything digital in the US, you can send users to your own web checkout today and Apple takes nothing from that sale. That has been true since the contempt ruling in Epic v. Apple in April 2025, and it still holds while a court works out what Apple may charge instead. Apple’s opening bid is 15%. Epic’s answer is close to zero.
For developers the window is open now, and it won’t stay free forever. What you build in the meantime should hold up whichever number the court lands on.
Screening App Ideas Before You Write Code: Four Questions, Starting With Who Pays
App ideas cost nothing. Every one of them looks shippable in a weekend, and then the weekend turns into three months of auth flows, sync bugs, review notes and a paywall that took longer than the app.
So before Xcode or Android Studio opens, put the idea through four questions and write the answers down. Who pays? What problem does it solve? Can you say what it does in one sentence? Why would anyone switch, and what stops Apple from copying it? Ask them in that order. Money goes first because it kills weak ideas fastest, while a kill still costs an evening.
The Side Project App Is Not Dead. The Side Project App Business Is.
The romantic narrative of the solo developer who builds an app in nights and weekends, publishes it to the App Store, and generates meaningful income from passive sales is not entirely false. It is sufficiently true in enough specific cases to sustain the mythology and sufficiently rare to make the mythology dangerous as a planning assumption.
The structural conditions that made the App Store a viable path to meaningful passive income for individual developers in 2010 to 2015 have changed. The App Store had fewer apps. Discovery was less competitive. Users were more willing to pay upfront for apps they had not tried. The apps that met a basic need in a well-executed way could find their audience without significant marketing investment.
The App Monetization Landscape Has Changed and Most Teams Have Not Caught Up
Apple’s App Tracking Transparency framework, which required explicit user permission for cross-app tracking, reduced mobile advertising effectiveness in ways the industry understood theoretically in 2021 and has spent the subsequent years quantifying empirically. The quantification has not been favorable. CPMs for iOS advertising inventory dropped significantly in the period following ATT’s rollout. Attribution accuracy — the ability to connect an ad impression to a downstream app install or purchase — declined materially. The precision-targeted mobile advertising ecosystem that had been the dominant growth channel for consumer apps was not destroyed, but it was substantially impaired.
The Subscription Model Reckoning Is Hitting Mobile Apps Hard
The subscription model’s dominance of mobile app monetization was, until recently, treated as a settled question. One-time purchases were dead. Advertising was privacy-constrained and algorithmically contested. Subscriptions provided predictable revenue, lower upfront friction, and the renewal economics that made customer lifetime value calculations favorable. Every growth deck from 2018 to 2022 told the same story about subscriptions being the obvious answer.
The reckoning that followed was predictable to anyone paying attention to the demand side of that story. Users had subscribed to enough things. The subscription fatigue that entertainment services experienced — as the number of streaming subscriptions a household maintained reached and exceeded what they were willing to pay — extended to software. Productivity apps, fitness apps, photo editors, and note-taking tools all compete for a monthly budget that users have become conscious of in ways they were not during the subscription model’s initial adoption phase.
The App Store's 30 Percent Problem Is Not Going Away Quietly
Apple’s App Store commission structure has been the subject of regulatory scrutiny, antitrust litigation, developer revolt, and congressional testimony for five years. The outcome of all this attention is a commission structure that has changed at the margins while remaining fundamentally intact at its core. The 30 percent standard rate — reduced to 15 percent for developers earning under a million dollars annually and for certain subscription renewals — continues to apply to the overwhelming majority of App Store revenue.
Tag: no-code
AI App Builders by Use Case: Lovable, Bolt.new, Replit Agent, Softr, FlutterFlow and v0
The AI app builder market is usually ranked as a single leaderboard, which is the wrong shape for it. These tools are not competing for the same job. Sorting them by what they actually produce, and for whom, gives a far more useful picture than any overall score.
Prompt-to-app and full-stack MVPs
These convert natural language into working full-stack applications or rapidly scaffolded prototypes.
Lovable. Built for non-developers, product managers and founders who want fast SaaS prototyping. It generates clean React and Tailwind frontend code paired with built-in Supabase backend infrastructure, authentication and continuous GitHub sync.
AI App Builders Reviewed: Lovable, Base44, Bolt, Replit and v0 Compared
Every one of these platforms will take a sentence and hand you a running application. That part is settled, and it works. What separates them is everything that happens afterwards: what the bill looks like in month three, whether you can take the code somewhere else, and whether the app is open to the internet by default.
They also get lumped into one category when they belong in three. Hosted prompt-to-app builders (Lovable, Base44, Bolt, Replit) generate and host the whole thing. UI-first generators like v0 hand you code and leave hosting to you. Editor and terminal agents such as Cursor and Claude Code sit inside a real repository and assume you can read the output. Security researchers draw the line in the same place, and for a reason: the editor tools require a human to review code before it ships, while the builders generate, execute and deploy with almost no oversight in between.
Verdent Updates AI Platform to Function as a Full Engineering Team for Solo Builders
Verdent has updated its AI-native software platform to operate across the full build cycle — planning, execution, validation, and delivery — rather than stopping at code generation. The update positions Verdent less as a coding assistant and more as a substitute for an engineering team, handling the sequence of decisions and handoffs that typically require multiple people to coordinate.
The gap between a software idea and a shipped product is not usually an ideas problem. It is a labor and coordination problem. Crossing it has historically required hiring engineers, managing sprints, and absorbing the context loss that comes with every handoff. Verdent’s design premise is that AI can now carry that load end-to-end: breaking a goal into tasks, selecting appropriate tooling, writing and testing code, and continuing work asynchronously through Slack or Telegram integrations even when the user is away. Context is retained across sessions, including stack decisions, prior build choices, and current state, so work does not reset between conversations.
Tag: observability
Screening 20 Infrastructure Primitives Money First: Why Distill and Precomputing Survive
Run the 20 primitive project ideas through the four-question screen strictly and the ranking changes a lot. Several technically attractive ideas turn into weak projects. The economic buyer is unclear, free infrastructure already solves the problem well enough, or the moat amounts to “ours is smaller.”
So Statefile, Lease, BareQueue, TTL, Count, Remember, Freeze and probably ConfigLog go out at this stage. They all solve real engineering problems, but the money question is poor. Redis, SQLite, existing Go libraries, message queues, object storage, Git and cloud infrastructure already give acceptable answers. A tiny implementation might make a respectable GitHub project. “Simpler and smaller” doesn’t tell you who eventually writes a meaningful check.
A Single-File Log Database: Pipe Logs In, Query Them With SQL, Hand the File to Anyone
The incident is over, the postmortem is Thursday, and someone wants the logs from the bad three hours. You can attach a gzip nobody will open, paste a screenshot of a grep, or stand up a search cluster to answer one question. The question is usually “which paths returned 500, and when did it start”, which has a GROUP BY hiding in it, and a GROUP BY is where grep runs out. A full observability stack answers it, but that’s a heavy answer for a team that doesn’t already run one.
A Telemetry Database That Forgets on Purpose Keeps Rollups and Anomalies Instead of Raw Rows
At 300 requests a second, one latency metric adds about 26 million rows a day. Nobody will read most of them again. What people ask for a month later is the p99 per route for last Tuesday, and the one request that took nine seconds. A rule that deletes rows after 30 days throws away both answers. Keeping every row forever pays storage bills for data nobody reads.
The telemetry store worth building decides at write time what has to survive. It folds everything else into coarser buckets on a schedule and keeps the few raw events that carry information, whole. Forgetting becomes part of the schema, declared in a policy, instead of a cron job that deletes by age. This is the argument for reducing data near the source, applied to time series.
Debug From a Timeline of State Changes Instead of Ten Thousand Log Lines
A ticket comes in: order 8812 shows as cancelled, but the customer’s card was charged. You open log search. The checkout service wrote a couple of hundred lines for that request; the payment webhook handler wrote a few dozen; the job that expires unpaid orders wrote a line for every order it looked at that minute. The answer is in there somewhere. Forty minutes later you find it. The expiry job cancelled the order thirty seconds after checkout began, and the payment provider’s webhook landed half a second after that.
Group Errors by Behavioral Signature Instead of Stack Trace Text
Add six lines to the top of a file and ship it. Every stack trace through that file now carries different line numbers, so a tracker that hashes the trace files a bug it has seen a hundred times as a brand-new issue. Meanwhile an older issue titled TimeoutError has collected comments from people who each fixed a different timeout and wondered why it never closed.
Grouping fails in both directions at once. One bug turns into hundreds of issues because the message embeds an order ID, the line numbers moved, or a framework upgrade changed the frames in the middle. Two bugs turn into one because every timeout in the codebase raises the same exception type from the same retry helper.
Most Log Volume Is a Few Templates Repeated, So Reduce Logs Locally Before Shipping Them
Take a day of production logs from one service, mask the numbers, IDs and quoted strings in every line, and sort the resulting patterns by how often they occur. The top of that list is short and dull: health checks, cache hits, a retry notice from a client library nobody owns. Each of those lines was serialized, shipped, parsed and indexed millions of times to say the same thing, and you paid for every copy. Run it on your own logs. The claim is easy to check, so don’t take it on faith.
Verified Absence Is Evidence: A Database for Recording That You Checked and Nothing Was There
An auditor asks you to show that customer 1187 was screened against a sanctions list on March 3. The screening job writes a row when it finds a match, and customer 1187 has no rows. That fits two histories: the job ran and found nothing, or the job never ran. The database can’t tell them apart, so you hold no evidence either way.
This is the closed-world assumption doing what SQL has always done: a row that doesn’t exist is false. RDF and OWL went the other way with an open-world assumption, where a missing statement means unknown. Neither has a place for the sentence you actually want to store: I looked here, in this way, at this time, and found nothing.
Tag: offline-first
Database-to-Database Sync for Local-First Apps Lives or Dies on Conflict Rules
Take a field technician who edits a work order on a tablet in a basement with no signal. Upstairs, the office edits the same order from a desk. Both hit save at 10:42 by their own clocks, and one of those clocks is ninety seconds off. When the tablet finds a signal, the sync layer has to produce one order that both people can live with. That decision is the product. Offline-first apps are harder than they look, and a large share of the difficulty sits in this one step.
Building Offline-First Mobile Apps Is Harder Than It Looks and Worth It
The default architecture for most mobile applications treats network connectivity as a reliable precondition. API calls are made on demand. Failures produce error states. The user waits for responses. This architecture produces apps that work acceptably on fast, reliable connections and badly on slow, intermittent, or absent connections — which describes the conditions under which many mobile users actually use apps.
Offline-first architecture inverts this assumption. The app reads from and writes to local storage first. Network synchronization happens in the background, opportunistically, whenever connectivity permits. The user experience is fast and available regardless of network state. The complexity is in the synchronization layer, which most teams underestimate significantly before they build it.
Tag: open source
20 Primitive Project Ideas: Tiny Go Engines That Do the Essential 10% of Redis, Kafka and Etcd
Given the direction of AltSql, BareProxy, Precomputing and the VPN primitives work, there is still a surprisingly large design space for projects that are smaller than platforms but more fundamental than ordinary applications. The best candidates have a very simple sentence behind them: “X currently requires a framework, service or stack; this does the essential 10% in one tiny binary, library or file.”
Look for primitives that can begin as a credible 2,000–10,000-line Go project, have an immediately understandable demo, and later sit underneath commercial products rather than needing to become a SaaS business immediately. Here are twenty directions that fit that model.
One Binary, One File, No Daemon: The SQLite and nginx Pattern as a Product Strategy
Compare two quickstarts. The first says to install Docker, bring up a compose file with a database, a cache and a worker, create an account, and paste a token into an env file. The second says to download one file and run it. Both tools might solve the same problem. Only one of them survives an evaluation that lasts ten minutes.
The second quickstart is a product decision, made in the architecture. SQLite and nginx made it decades ago, and Caddy, DuckDB, ripgrep, jq and Hugo have made it again in their own corners. Small surface area, few dependencies and one artifact to copy work as an adoption strategy. For a one-person or AI-assisted project they also work as the only scope control that holds up. That’s the claim, and the rest of this post tries to break it.
DigitalOcean Launches AI-Native Cloud at Deploy 2026
DigitalOcean has announced the DigitalOcean AI-Native Cloud, positioning itself as the first cloud platform built end-to-end for the inference and agentic era. The launch took place at Deploy 2026, the company’s annual conference for builders, and the platform is available to customers today.
The Problem It’s Solving
AI developers have long been squeezed between two imperfect options: hyperscalers like AWS with enterprise-grade complexity and unpredictable costs, or newer GPU clouds that hand you bare metal and tokens but leave you to wire everything else together yourself. DigitalOcean is pitching its AI-Native Cloud as the third path — a fully integrated stack that handles infrastructure through agents, without the assembly tax.
Tag: performance
Mobile App Performance: The Five Metrics That Decide Retention and Store Ratings
Performance work in mobile development wastes more effort than almost any other kind of engineering. Teams burn sprints shaving milliseconds off benchmarks that no user will ever feel. Meanwhile the problems that actually make people uninstall, the freezes, the janky feeds, the phone that’s dead by 4pm, sit in the backlog because nobody put a number on them.
The gap between what’s easy to measure and what users care about is wide. Closing it starts with picking the right metrics.
Facts Should Expire: A Database That Tells an AI Agent When Its Knowledge Has Gone Stale
An agent keeps a memory table, and two rows matter for today’s task: a supplier’s headquarters city, written eleven months ago, and a freight quote, written three hours ago. A SELECT returns both in the same shape. The headquarters is probably still right. The quote may already be wrong. Nothing in either row says so, and the agent repeats both in the same flat tone.
A row has no idea how old its truth is. It might carry a created_at, and a careful person can compute an age from it, but the decay rate belongs to the kind of fact, not to the table. A three-week-old headquarters address is fine. A three-week-old shipping rate is fiction. Server health goes bad in half a minute. No timestamp column holds that knowledge, and nothing forces a query to read it anyway.
Give Every Database Query a Budget and Fail the Build When It Scans Too Much
A developer changes a login lookup to WHERE lower(email) = lower($1) so that sign-in stops being case-sensitive. Every test passes. The btree index on email can’t serve a query that wraps the column in a function, so Postgres reads the whole users table, and on a test database with forty rows that’s the cheapest plan anyway. The change ships. A week later someone notices login latency tracking the signup count. The fix is a one-line expression index that would have taken a minute if anything had objected during review.
Incremental View Maintenance Small Enough to Embed Turns Dashboard Queries Into Lookups
A dashboard tile shows today’s US traffic, so every page load runs SELECT count(*) FROM events WHERE country = 'US' over a table that grew by a few hundred thousand rows since yesterday. SQLite answers correctly. It also walks every matching index entry to do it, because its b-trees don’t keep counts, and it does the same walk for the next viewer and the one after. Between two page loads the answer moves by a handful of rows, yet each load pays for all of them.
Most Log Volume Is a Few Templates Repeated, So Reduce Logs Locally Before Shipping Them
Take a day of production logs from one service, mask the numbers, IDs and quoted strings in every line, and sort the resulting patterns by how often they occur. The top of that list is short and dull: health checks, cache hits, a retry notice from a client library nobody owns. Each of those lines was serialized, shipped, parsed and indexed millions of times to say the same thing, and you paid for every copy. Run it on your own logs. The claim is easy to check, so don’t take it on faith.
Application Performance Optimization: Where Most Teams Waste Their Time
A team spends three weeks rewriting a hot loop in Rust bindings, shaves forty milliseconds off a function that runs once per request, and ships it. The page still takes four seconds to load. Nobody profiled first. That’s the pattern behind most performance work that goes nowhere: real effort, wrong target.
Optimization only pays off when you know where the time actually goes, and that’s rarely where intuition points. Developers tend to suspect their own code, because that’s the part they wrote and the part they can picture running slowly. The database, the network, the third-party API call buried in a middleware layer — those stay invisible until you measure them.
Tag: postgresql
A Schema Diff That Warns Which Migration Will Lock a 40-Million-Row Table or Lose Data
The diff in the pull request is one line: ALTER TABLE orders ALTER COLUMN total TYPE bigint;. It reads like a rounding fix, so the reviewer approves it, and the SQL is correct. On a table with 41 million rows it’s also a full rewrite under a lock that stops every read and write until it finishes. A diff shows what changes, never what the change costs.
A schema diff worth using would print consequences instead of SQL, in sentences like “this rewrites a 41-million-row table and blocks every read and write” or “the rollback is impossible without a backup”. Those sentences depend on three things: the statement, the engine and its version, and the size of the table it lands on. With all three you can post a risk report on every migration pull request. With only the first you have a linter.
Give Every Database Query a Budget and Fail the Build When It Scans Too Much
A developer changes a login lookup to WHERE lower(email) = lower($1) so that sign-in stops being case-sensitive. Every test passes. The btree index on email can’t serve a query that wraps the column in a function, so Postgres reads the whole users table, and on a test database with forty rows that’s the cheapest plan anyway. The change ships. A week later someone notices login latency tracking the signup count. The fix is a one-line expression index that would have taken a minute if anything had objected during review.
Tag: primitives
20 Primitive Project Ideas: Tiny Go Engines That Do the Essential 10% of Redis, Kafka and Etcd
Given the direction of AltSql, BareProxy, Precomputing and the VPN primitives work, there is still a surprisingly large design space for projects that are smaller than platforms but more fundamental than ordinary applications. The best candidates have a very simple sentence behind them: “X currently requires a framework, service or stack; this does the essential 10% in one tiny binary, library or file.”
Look for primitives that can begin as a credible 2,000–10,000-line Go project, have an immediately understandable demo, and later sit underneath commercial products rather than needing to become a SaaS business immediately. Here are twenty directions that fit that model.
40 Radically Different Infrastructure Primitives, From Reach and Expect to Ignorance and Stop
This list deliberately leaves “tiny version of Redis, Kafka or SQLite” territory behind. That was the first list of 20 primitives. The more interesting search space is a primitive that introduces a new operation, one developers might eventually feel should have existed all along. Some research paper or niche project has probably explored pieces of these. They’re meant as category-level concepts, not smaller copies of familiar products.
Forty primitives
1. Reach. Store a current state plus transition rules and continuously maintain which states are reachable from here: REACHABLE(current_state). A database answers what is; Reach answers what can happen. Uses: AI agent safety, workflows, infrastructure, manufacturing, cybersecurity attack paths.
Counterfactual Store vs. Markov Chains: From Branching State to Reach, an Engine for Possible Futures
The Counterfactual Store does resemble a Markov chain at the conceptual level. Both deal with states and the possible transitions between them. But a Markov chain is mainly a mathematical model for probabilistic transitions: given that I’m in state A, what’s the probability the next state is B, C or D? And the classic Markov property says the next-state probability depends on the current state, not the full history.
The Counterfactual Store is deterministic branching, not probabilistic transition. If the current application state is A, you create a hypothetical A′, change something, propagate the consequences, inspect the result and throw it away without touching A. No probability needs to be involved anywhere.
Counterfactual Store: A Database That Stores Alternatives, Not Just Facts
One direction that feels genuinely different from the earlier list of 20 primitives is a Counterfactual Store. Adjacent ideas certainly exist. Provenance databases, event sourcing, probabilistic databases, simulation systems and version control all touch pieces of it. But as a deliberately tiny infrastructure primitive, there’s no established category built around this exact abstraction.
Normal databases answer “what is true?” Temporal databases, and Temporal KV, add “what was true?” A Counterfactual Store adds a third basic question: what would be true if X were different?
Screening 20 Infrastructure Primitives Money First: Why Distill and Precomputing Survive
Run the 20 primitive project ideas through the four-question screen strictly and the ranking changes a lot. Several technically attractive ideas turn into weak projects. The economic buyer is unclear, free infrastructure already solves the problem well enough, or the moat amounts to “ours is smaller.”
So Statefile, Lease, BareQueue, TTL, Count, Remember, Freeze and probably ConfigLog go out at this stage. They all solve real engineering problems, but the money question is poor. Redis, SQLite, existing Go libraries, message queues, object storage, Git and cloud infrastructure already give acceptable answers. A tiny implementation might make a respectable GitHub project. “Simpler and smaller” doesn’t tell you who eventually writes a meaningful check.
Temporal KV: A Key-Value Store That Remembers History
Temporal KV is a key-value database where a key doesn’t just have a current value. The database automatically remembers how that value changed over time.
In an ordinary KV store, you might write price = 100, then later price = 110, then price = 125. Ask for price and you get 125. The earlier values have normally been overwritten. In a Temporal KV store, all three states stay logically accessible. You can ask for the current value and get 125, or ask “what was price at 10:00 yesterday?” and get 100. The basic abstraction stops being key → value. It becomes key + time → value.
Tag: project spotlight
AltSql: Gives IoT Devices a 15 KB Database That Keeps Working When the Link Drops
Anyone who has built the software side of a connected product knows the integration job. The device keeps its readings and settings in one format and the gateway or cloud service wants those same values as rows in a SQL database. Somebody writes a converter. Then somebody has to keep that converter alive for as long as the device stays in the field, which for industrial equipment or embedded systems can easily be ten years. The converter has to handle offline periods, retries, out-of-order updates, and the device’s own data format changing over time.
BareProxy: A Small Go Web Server and Reverse Proxy That Explains Every Routing Decision
Most sites run a thin slice of nginx in front of their application: TLS termination, serving static files from a folder, a couple of routes to a backend service, health checks, and the occasional reload. The configuration grows anyway, one regular expression at a time, until nobody is quite sure which block handles a given URL, and a change that looks safe to one person breaks something in production that another person didn’t know existed.
Precomputing: Keeps Dashboard Answers Ready in a SQLite File as the Data Arrives
Most dashboards ask the same few questions all day long: requests per endpoint, month-to-date usage for one customer, error rates by status code. The usual setup recounts raw rows from scratch on every refresh, or ships every row to a hosted analytics service that bills by the gigabyte. A dashboard that needs to answer quickly on demand either waits for a database query to finish, or pays for a service that stores everything.
Preconfiguration: Writes Coding Agent Setup Files From One Spec and Tests Them on a Clean Machine
Cloud coding agents start each task on a fresh machine. Before the agent can run a single test, something has to install the right runtime, start a database, configure environment variables, and download dependencies. Every platform that runs agents wants those instructions in its own file: Copilot expects a setup workflow, Cursor builds a Dockerfile, other platforms want shell scripts or configuration in other formats. A team that uses two or three agents writes the same setup two or three times, and mistakes usually show up later as an agent session that stalls because a database port wasn’t open or a runtime was the wrong version.
VPN Works: Gives Each AI Agent Its Own Network and a Record of Every Connection
A coding agent spends its day reading text written by strangers: issues on your issue tracker, snippets pasted into prompts, code from repositories, instructions on web pages. One malicious instruction planted in that text can be enough to make an agent send a deploy token somewhere it shouldn’t. On a machine-wide VPN, that request leaves the same way as everything else, and afterwards nobody can say which program sent it.
Tag: python
Asynchronous Programming in Python: How the Event Loop, Event Queue, and Thread Pool Fit Together
Asynchronous code has a reputation for being confusing, but the core idea is simple: stop waiting. This post starts from zero — no prior async experience assumed — and builds up to the parts people usually find murky: how the event queue, the event loop, and the thread pool connect, and what coroutines, await, futures, tasks, gather, queues, cancellation, and starvation actually mean. Every concept comes with a small, runnable example.
Tag: react native
State Management in React Native Has Too Many Options and One Right Answer
The React Native state management ecosystem is the most frequently relitigated technical decision in mobile JavaScript development. Every twelve to eighteen months, a new library emerges, accumulates advocates, generates a wave of “why I switched from X to Y” blog posts, and joins the list of options that teams now have to evaluate. The list includes Redux, MobX, Zustand, Jotai, Recoil, TanStack Query, SWR, Context API, and several others with smaller followings. The churn produces the impression that state management is an unsolved problem requiring continuous reinvention.
Cross-Platform vs Native: The Honest Assessment Nobody Gives You
The cross-platform vs native debate has a quality problem: the people most qualified to give objective assessments have financial or professional stakes in one answer. Agency developers who charge by the hour prefer native because it doubles the billable work. Cross-platform framework vendors publish benchmark comparisons designed to minimize the gaps between their output and native. Native platform advocates at Apple and Google have obvious incentives to characterize cross-platform output as inferior.
React Native in 2026: Mature, Imperfect, Indispensable
React Native was announced by Facebook in 2015 with a promise that rewrote the calculus of mobile development: learn once, write anywhere. The promise was qualified from the start — React Native was never write once, run anywhere in the way that early web-based mobile frameworks had claimed to be — but it was credible enough to reshape how a generation of mobile teams made technology decisions.
Eleven years later, React Native is used in production by Microsoft, Shopify, Coinbase, and thousands of smaller organizations. It has survived the emergence of Flutter, the maturation of Kotlin Multiplatform, and a period of internal uncertainty at Meta when the framework’s future was genuinely in question. Its survival reflects something real about the problem it solves and the ecosystem it has built.
Tag: security
Configuration Drift Lives Between Files, So Lint Env Files, YAML, TOML and CI Together
.env.example says DATABASE_URL=postgres://localhost:5432/app. The compose file the team uses for local work mounts a volume and sets DATABASE_URL=sqlite:///data/app.db. The CI workflow exports DB_URL, a name the code stopped reading two refactors ago. Production has a secret called DATABASE_URL that nobody has looked at since the last rotation. Each of those files is valid, and every linter you could point at them passes them. The app still behaves differently on three machines, and the first person to find out is whoever is on call.
Mapping Every Dependency to the Features That Break If It Disappears Tomorrow
Run npm ls --all on a mid-sized web app and you get a tree that scrolls for pages. It’s accurate and complete, and on the morning a maintainer deletes a package it tells you almost nothing. You can see that tiny-util sits three levels down. You can’t see whether losing it breaks the checkout page or a script nobody has run since spring.
A dependency tree answers “what do I depend on”. The question that matters is “what breaks, and for whom, if this package vanishes or turns hostile”. They need different data. The tree comes from a lockfile. The answer comes from your own source: which functions call the package, which routes, commands and jobs those functions serve, and how much code would change to replace it. A tool that produced that for every package would turn dependency management from an inventory into something a product owner can read.
VPN Works: Gives Each AI Agent Its Own Network and a Record of Every Connection
A coding agent spends its day reading text written by strangers: issues on your issue tracker, snippets pasted into prompts, code from repositories, instructions on web pages. One malicious instruction planted in that text can be enough to make an agent send a deploy token somewhere it shouldn’t. On a machine-wide VPN, that request leaves the same way as everything else, and afterwards nobody can say which program sent it.
Mobile Security: What Developers Consistently Get Wrong
Mobile security vulnerabilities cluster in a predictable set of categories. The same mistakes appear in security audits of consumer apps, enterprise apps, and fintech apps with equal regularity. The recurrence of the same errors across different teams and different organizations suggests that the failures are not primarily due to ignorance — most mobile developers are aware that security matters — but to a gap between security knowledge and the specific engineering practices that translate that knowledge into secure code.
Tag: side projects
20 Primitive Project Ideas: Tiny Go Engines That Do the Essential 10% of Redis, Kafka and Etcd
Given the direction of AltSql, BareProxy, Precomputing and the VPN primitives work, there is still a surprisingly large design space for projects that are smaller than platforms but more fundamental than ordinary applications. The best candidates have a very simple sentence behind them: “X currently requires a framework, service or stack; this does the essential 10% in one tiny binary, library or file.”
Look for primitives that can begin as a credible 2,000–10,000-line Go project, have an immediately understandable demo, and later sit underneath commercial products rather than needing to become a SaaS business immediately. Here are twenty directions that fit that model.
40 Projects Worth Building: SQLite for X, Tiny Infrastructure, MCP Tools and Edge Systems
The most promising territory for a small team isn’t another large framework. It’s the opposite: infrastructure software you can explain in one sentence, ship as one binary or embed as one library, run with almost no operational burden, and that solves one irritating problem unusually well. SQLite and nginx are the right mental models because their appeal is architectural, not just functional: small surface area, predictable behavior, few dependencies, easy deployment, and usefulness far beyond the original use case. (More on that in the SQLite and nginx pattern as a product strategy.)
40 Radically Different Infrastructure Primitives, From Reach and Expect to Ignorance and Stop
This list deliberately leaves “tiny version of Redis, Kafka or SQLite” territory behind. That was the first list of 20 primitives. The more interesting search space is a primitive that introduces a new operation, one developers might eventually feel should have existed all along. Some research paper or niche project has probably explored pieces of these. They’re meant as category-level concepts, not smaller copies of familiar products.
Forty primitives
1. Reach. Store a current state plus transition rules and continuously maintain which states are reachable from here: REACHABLE(current_state). A database answers what is; Reach answers what can happen. Uses: AI agent safety, workflows, infrastructure, manufacturing, cybersecurity attack paths.
Counterfactual Store vs. Markov Chains: From Branching State to Reach, an Engine for Possible Futures
The Counterfactual Store does resemble a Markov chain at the conceptual level. Both deal with states and the possible transitions between them. But a Markov chain is mainly a mathematical model for probabilistic transitions: given that I’m in state A, what’s the probability the next state is B, C or D? And the classic Markov property says the next-state probability depends on the current state, not the full history.
The Counterfactual Store is deterministic branching, not probabilistic transition. If the current application state is A, you create a hypothetical A′, change something, propagate the consequences, inspect the result and throw it away without touching A. No probability needs to be involved anywhere.
Counterfactual Store: A Database That Stores Alternatives, Not Just Facts
One direction that feels genuinely different from the earlier list of 20 primitives is a Counterfactual Store. Adjacent ideas certainly exist. Provenance databases, event sourcing, probabilistic databases, simulation systems and version control all touch pieces of it. But as a deliberately tiny infrastructure primitive, there’s no established category built around this exact abstraction.
Normal databases answer “what is true?” Temporal databases, and Temporal KV, add “what was true?” A Counterfactual Store adds a third basic question: what would be true if X were different?
Screening 20 Infrastructure Primitives Money First: Why Distill and Precomputing Survive
Run the 20 primitive project ideas through the four-question screen strictly and the ranking changes a lot. Several technically attractive ideas turn into weak projects. The economic buyer is unclear, free infrastructure already solves the problem well enough, or the moat amounts to “ours is smaller.”
So Statefile, Lease, BareQueue, TTL, Count, Remember, Freeze and probably ConfigLog go out at this stage. They all solve real engineering problems, but the money question is poor. Redis, SQLite, existing Go libraries, message queues, object storage, Git and cloud infrastructure already give acceptable answers. A tiny implementation might make a respectable GitHub project. “Simpler and smaller” doesn’t tell you who eventually writes a meaningful check.
Temporal KV: A Key-Value Store That Remembers History
Temporal KV is a key-value database where a key doesn’t just have a current value. The database automatically remembers how that value changed over time.
In an ordinary KV store, you might write price = 100, then later price = 110, then price = 125. Ask for price and you get 125. The earlier values have normally been overwritten. In a Temporal KV store, all three states stay logically accessible. You can ask for the current value and get 125, or ask “what was price at 10:00 yesterday?” and get 100. The basic abstraction stops being key → value. It becomes key + time → value.
A Background Job Queue in One SQLite File Covers What Most Apps Deploy Redis For
A signup handler has to send a welcome email, and sending it inline puts a third-party API call inside your request. So you move it into a background job, and the usual next step is Redis, a client library, a worker process, a dashboard, and a note in the deploy docs about what happens to queued jobs when Redis restarts without persistence. If the app runs on one machine, you’ve added a second stateful service to look after a table’s worth of data.
A Database Where Every Value Remembers Its Source, Confidence and Extraction Time
Somebody pastes a population figure into a shared spreadsheet: 1,234,567. It might have come from a census table, a Wikipedia infobox, a city press release or a model’s summary of one of those, and three weeks later nobody can say which. The paste kept the digits. Everything that made them believable stayed in a browser tab that closed long ago.
A value without provenance is a rumor with a data type.
A Feature Store Small Enough to Embed: Point-in-Time Reads for Local and Edge ML
A churn model looks excellent in the notebook and mediocre in production. The model isn’t broken. The training table computed orders_7d with a rolling window over the full history, so some rows counted orders placed after the label date. The serving code, written later in another language, counts a calendar week instead of seven days. One feature, two definitions, and a quiet look into the future. Those are the two bugs a feature store exists to prevent: training-serving skew and label leakage.
A Schema Diff That Warns Which Migration Will Lock a 40-Million-Row Table or Lose Data
The diff in the pull request is one line: ALTER TABLE orders ALTER COLUMN total TYPE bigint;. It reads like a rounding fix, so the reviewer approves it, and the SQL is correct. On a table with 41 million rows it’s also a full rewrite under a lock that stops every read and write until it finishes. A diff shows what changes, never what the change costs.
A schema diff worth using would print consequences instead of SQL, in sentences like “this rewrites a 41-million-row table and blocks every read and write” or “the rollback is impossible without a backup”. Those sentences depend on three things: the statement, the engine and its version, and the size of the table it lands on. With all three you can post a risk report on every migration pull request. With only the first you have a linter.
A Single-File Log Database: Pipe Logs In, Query Them With SQL, Hand the File to Anyone
The incident is over, the postmortem is Thursday, and someone wants the logs from the bad three hours. You can attach a gzip nobody will open, paste a screenshot of a grep, or stand up a search cluster to answer one question. The question is usually “which paths returned 500, and when did it start”, which has a GROUP BY hiding in it, and a GROUP BY is where grep runs out. A full observability stack answers it, but that’s a heavy answer for a team that doesn’t already run one.
A Telemetry Database That Forgets on Purpose Keeps Rollups and Anomalies Instead of Raw Rows
At 300 requests a second, one latency metric adds about 26 million rows a day. Nobody will read most of them again. What people ask for a month later is the p99 per route for last Tuesday, and the one request that took nine seconds. A rule that deletes rows after 30 days throws away both answers. Keeping every row forever pays storage bills for data nobody reads.
The telemetry store worth building decides at write time what has to survive. It folds everything else into coarser buckets on a schedule and keeps the few raw events that carry information, whole. Forgetting becomes part of the schema, declared in a policy, instead of a cron job that deletes by age. This is the argument for reducing data near the source, applied to time series.
A Tiny SQL Engine for JSON Streams Fits Between jq and a Stream Processing Cluster
Your service writes one JSON object per line to stdout, and you want the average cpu for host web-3 over the last five minutes. jq can’t answer that, because it forgets each object once it has printed it and has no idea what “five minutes” means. You can fake both with jq -n 'reduce inputs as $e (...)' plus a timestamp comparison, and you’ll have a script nobody wants to touch twice. DuckDB answers the question in one line, but only against a file as it exists right now. ksqlDB, Materialize, RisingWave, Arroyo and Flink SQL answer it continuously, once you’ve deployed a service and agreed to operate it.
An Embedded Sketch Database: Billions of Events, Megabytes of Storage, Error Bars on Every Answer
Counting unique visitors exactly means remembering every visitor. Say 6 million distinct IPv4 addresses hit a checkout service today. Packed at 4 bytes each, that set is 24 MB before any hash table overhead, and you need one per service, per region, per day you want to compare. Redis answers the same question with a HyperLogLog in about 12 KB per key, at a standard error of about 0.81%.
The thin part is the database around it: a SQLite-shaped file of sketches with time buckets, rollups and a SQL front door (check before you start; this space moves). The version worth building stores nothing but mergeable sketches, grouped by dimension and time bucket, and every aggregate returns its error bound next to the value. You never keep the events. It’s the extreme case of reducing data near the source: keep the answer, drop the rows.
An Embedded Workflow Engine With Five Primitives: Trigger, Condition, Action, Wait and Retry
A user signs up on Monday. If they haven’t activated by Wednesday, you send a nudge email, and if the email provider times out, you try a few more times before flagging the account. That’s the whole spec. Most teams build it as a cron job that scans for users in the wrong state, a nullable nudge_sent_at column and a retry loop written late on a Friday. It holds until the cron overlaps itself, or a deploy lands mid-loop, or the provider times out after actually sending the message and one customer gets three emails.
An Evidence Graph Built From Extracted Claims Keeps Contradictions Attached to Their Sources
Feed forty articles about a rumored plant restart to a summarizer and you get one smooth paragraph: several outlets report that production will resume in March, though the ministry has pushed back. It reads well. It also throws away what you’d need to act on it. You can’t tell which outlets reported it, whether each had its own source or all copied one wire story, or what the ministry actually said, a denial or a polite refusal to comment.
Configuration Drift Lives Between Files, So Lint Env Files, YAML, TOML and CI Together
.env.example says DATABASE_URL=postgres://localhost:5432/app. The compose file the team uses for local work mounts a volume and sets DATABASE_URL=sqlite:///data/app.db. The CI workflow exports DB_URL, a name the code stopped reading two refactors ago. Production has a secret called DATABASE_URL that nobody has looked at since the last rotation. Each of those files is valid, and every linter you could point at them passes them. The app still behaves differently on three machines, and the first person to find out is whoever is on call.
Context Window Management as a Database: Ask for 12,000 Tokens, Get the Most Useful Ones
An agent is ninety tool calls into a refactor. Step 12 was a grep that returned 52 KB, and all of it is still in the prompt. The user’s instruction from step 1, “never touch db/migrations”, fell out of the window ten steps ago, because the framework drops the oldest messages first. The agent edits a migration. Nothing malfunctioned; the truncation rule did exactly what it was written to do.
Cron for AI Agents: Schedules, Timeouts, Overlap Rules and Cost Ceilings in One Config File
A nightly agent job triages new issues. One night an issue arrives with a 400 KB log attached. The agent reads it, a tool call fails, the agent retries, and the loop runs until the month’s token budget is gone. Meanwhile cron, which has no idea what a token is, starts the next run on schedule. Now two copies are fighting over the same issue tracker.
Cron was built for jobs that cost nothing, finish in seconds and do the same thing every time. Agent jobs cost money per token, run for an unpredictable time and can loop. The useful ones are still boring and periodic: summarize what changed in a repo since yesterday, triage new issues each morning, check a competitor’s pricing page weekly. What they need is a scheduler that stays as small as cron and adds four things: a cost ceiling, a timeout that actually kills, an overlap rule, and state carried between runs. Anything past that is an orchestration platform, a different and much larger product.
Database-to-Database Sync for Local-First Apps Lives or Dies on Conflict Rules
Take a field technician who edits a work order on a tablet in a basement with no signal. Upstairs, the office edits the same order from a desk. Both hit save at 10:42 by their own clocks, and one of those clocks is ninety seconds off. When the tablet finds a signal, the sync layer has to produce one order that both people can live with. That decision is the product. Offline-first apps are harder than they look, and a large share of the difficulty sits in this one step.
Debug From a Timeline of State Changes Instead of Ten Thousand Log Lines
A ticket comes in: order 8812 shows as cancelled, but the customer’s card was charged. You open log search. The checkout service wrote a couple of hundred lines for that request; the payment webhook handler wrote a few dozen; the job that expires unpaid orders wrote a line for every order it looked at that minute. The answer is in there somewhere. Forty minutes later you find it. The expiry job cancelled the order thirty seconds after checkout began, and the payment provider’s webhook landed half a second after that.
DuckDB Already Queries Every File in a Folder, So Build the Part That Infers the Joins
Someone hands you a zip: customers.csv from the CRM, a JSON dump from the billing API, and a SQLite file from an internal app nobody has touched in two years. DuckDB will make all three queryable in a few lines of SQL, with no import step (SELECT * FROM 'customers.csv' works as written). Then you spend the afternoon working out which column joins to which. The CRM says customer_id and stores 00123. The billing API says customerId and stores 123. The SQLite table has a column called customer holding the text 123. Same customer, three spellings.
Embedded Vector Search Is Crowded: What a One-File Vector Database Needs to Stand Out
You have 40,000 support articles and an app that should offer “similar articles”. Embedded at 768 dimensions in float32, that’s 40,000 × 768 × 4 bytes, about 123 MB of vectors. The standard advice is to stand up a vector database: a service, a port, credentials, a client library and a backup story for 123 MB. A file would do.
Below a few million vectors the server is the overhead, which is why the embedded field filled up fast. So the useful question is what a newcomer brings that the free libraries don’t. My answer is one sharp edge you can state in a sentence, plus measurements the others leave you to make yourself.
Facts Should Expire: A Database That Tells an AI Agent When Its Knowledge Has Gone Stale
An agent keeps a memory table, and two rows matter for today’s task: a supplier’s headquarters city, written eleven months ago, and a freight quote, written three hours ago. A SELECT returns both in the same shape. The headquarters is probably still right. The quote may already be wrong. Nothing in either row says so, and the agent repeats both in the same flat tone.
A row has no idea how old its truth is. It might carry a created_at, and a careful person can compute an age from it, but the decay rate belongs to the kind of fact, not to the table. A three-week-old headquarters address is fine. A three-week-old shipping rate is fiction. Server health goes bad in half a minute. No timestamp column holds that knowledge, and nothing forces a query to read it anyway.
Give Every Database Query a Budget and Fail the Build When It Scans Too Much
A developer changes a login lookup to WHERE lower(email) = lower($1) so that sign-in stops being case-sensitive. Every test passes. The btree index on email can’t serve a query that wraps the column in a function, so Postgres reads the whole users table, and on a test database with forty rows that’s the cheapest plan anyway. The change ships. A week later someone notices login latency tracking the signup count. The fix is a one-line expression index that would have taken a minute if anything had objected during review.
Group Errors by Behavioral Signature Instead of Stack Trace Text
Add six lines to the top of a file and ship it. Every stack trace through that file now carries different line numbers, so a tracker that hashes the trace files a bug it has seen a hundred times as a brand-new issue. Meanwhile an older issue titled TimeoutError has collected comments from people who each fixed a different timeout and wondered why it never closed.
Grouping fails in both directions at once. One bug turns into hundreds of issues because the message embeds an order ID, the line numbers moved, or a framework upgrade changed the frames in the middle. Two bugs turn into one because every timeout in the codebase raises the same exception type from the same retry helper.
Incremental View Maintenance Small Enough to Embed Turns Dashboard Queries Into Lookups
A dashboard tile shows today’s US traffic, so every page load runs SELECT count(*) FROM events WHERE country = 'US' over a table that grew by a few hundred thousand rows since yesterday. SQLite answers correctly. It also walks every matching index entry to do it, because its b-trees don’t keep counts, and it does the same walk for the next viewer and the one after. Between two page loads the answer moves by a handful of rows, yet each load pays for all of them.
Kafka for One Machine: An Embedded Event Log With Offsets, Compaction and No Broker
A desktop app wants an undo history that survives a crash. An edge gateway buffers sensor readings while its uplink is down and has to replay them, in order, once the link is back. An AI agent writes down every action it takes so a bad run can be replayed later. All three are the same data structure: an append-only sequence of records, plus readers that remember where they stopped. Kafka is that structure, and also a cluster, partitions and the people who tune them.
Mapping Every Dependency to the Features That Break If It Disappears Tomorrow
Run npm ls --all on a mid-sized web app and you get a tree that scrolls for pages. It’s accurate and complete, and on the morning a maintainer deletes a package it tells you almost nothing. You can see that tiny-util sits three levels down. You can’t see whether losing it breaks the checkout page or a script nobody has run since spring.
A dependency tree answers “what do I depend on”. The question that matters is “what breaks, and for whom, if this package vanishes or turns hostile”. They need different data. The tree comes from a lockfile. The answer comes from your own source: which functions call the package, which routes, commands and jobs those functions serve, and how much code would change to replace it. A tool that produced that for every package would turn dependency management from an inventory into something a product owner can read.
Most Log Volume Is a Few Templates Repeated, So Reduce Logs Locally Before Shipping Them
Take a day of production logs from one service, mask the numbers, IDs and quoted strings in every line, and sort the resulting patterns by how often they occur. The top of that list is short and dull: health checks, cache hits, a retry notice from a client library nobody owns. Each of those lines was serialized, shipped, parsed and indexed millions of times to say the same thing, and you paid for every copy. Run it on your own logs. The claim is easy to check, so don’t take it on faith.
One Binary, One File, No Daemon: The SQLite and nginx Pattern as a Product Strategy
Compare two quickstarts. The first says to install Docker, bring up a compose file with a database, a cache and a worker, create an account, and paste a token into an env file. The second says to download one file and run it. Both tools might solve the same problem. Only one of them survives an evaluation that lasts ten minutes.
The second quickstart is a product decision, made in the architecture. SQLite and nginx made it decades ago, and Caddy, DuckDB, ripgrep, jq and Hugo have made it again in their own corners. Small surface area, few dependencies and one artifact to copy work as an adoption strategy. For a one-person or AI-assisted project they also work as the only scope control that holds up. That’s the claim, and the rest of this post tries to break it.
Redis Semantics Without Redis: An Embedded State Engine for Counters, Leases and TTLs
A command-line tool should run only one copy of its nightly export at a time. A small web app wants to cap each user at 60 requests a minute. A desktop app needs to remember when it last synced. All three are state: an integer, a timestamp, an owner. All three usually get solved by adding Redis, because Redis has the verbs for them: INCR, SET NX PX, EXPIRE. The app needed the verbs and got a server along with them, a port and a persistence config included.
Spreadsheet Recalculation Inside a Database: Derived Values That Track Their Own Dependencies
A line item’s quantity goes from 4 to 5. The order subtotal should change, and so should the tax, the order total, the customer’s lifetime value and the regional revenue figure on a dashboard. Which of those actually update depends on which code path made the edit, because each one gets recomputed somewhere different: the checkout handler, the invoice renderer, a nightly job, a SQL view somebody wrote for finance. Every copy of the formula is another chance for two screens to disagree.
SQL and Key-Value Over the Same Bytes: An Old Database Idea Worth Making Small
A sensor node writes a reading every few seconds. The firmware wants one thing from storage: put a record by key, get it back by key, as fast as the flash allows. The dashboard on the gateway wants something else, like average temperature by sensor by hour, joined to a table of sites. The usual answer is two databases with a translation job between them, a key-value store on the device and SQLite or Postgres upstream. Then comes a year of debugging the translation: a unit that changed, a row that arrived twice, a field the device encodes one way and the gateway reads another.
Store Changes Instead of Current Rows: An Embedded Database Built Around History
A support ticket asks two plain questions: which plan was customer 4411 on when the August invoice went out, and who moved them off it? The customers table can’t answer either. It holds today’s row. The audit table someone added two years ago holds most of the story, apart from the week a data fix ran a bulk UPDATE in raw SQL and skipped the ORM callbacks that write the audit rows.
Verified Absence Is Evidence: A Database for Recording That You Checked and Nothing Was There
An auditor asks you to show that customer 1187 was screened against a sanctions list on March 3. The screening job writes a row when it finds a match, and customer 1187 has no rows. That fits two histories: the job ran and found nothing, or the job never ran. The database can’t tell them apart, so you hold no evidence either way.
This is the closed-world assumption doing what SQL has always done: a row that doesn’t exist is false. RDF and OWL went the other way with an open-world assumption, where a missing statement means unknown. Neither has a place for the sentence you actually want to store: I looked here, in this way, at this time, and found nothing.
Screening App Ideas Before You Write Code: Four Questions, Starting With Who Pays
App ideas cost nothing. Every one of them looks shippable in a weekend, and then the weekend turns into three months of auth flows, sync bugs, review notes and a paywall that took longer than the app.
So before Xcode or Android Studio opens, put the idea through four questions and write the answers down. Who pays? What problem does it solve? Can you say what it does in one sentence? Why would anyone switch, and what stops Apple from copying it? Ask them in that order. Money goes first because it kills weak ideas fastest, while a kill still costs an evening.
Nine Apps Worth Coding, and the Hard Part Buried in Each One
Every app idea has a boring 90% and a nasty 10%. The boring part is CRUD, auth, a settings page, Stripe. The nasty part is the one subsystem that decides whether the thing works at all, and it’s usually not the part that looks hard in the pitch. Below are nine builds worth attempting, with the nasty 10% named up front so you can decide whether you want to spend your weekends there.
The Side Project App Is Not Dead. The Side Project App Business Is.
The romantic narrative of the solo developer who builds an app in nights and weekends, publishes it to the App Store, and generates meaningful income from passive sales is not entirely false. It is sufficiently true in enough specific cases to sustain the mythology and sufficiently rare to make the mythology dangerous as a planning assumption.
The structural conditions that made the App Store a viable path to meaningful passive income for individual developers in 2010 to 2015 have changed. The App Store had fewer apps. Discovery was less competitive. Users were more willing to pay upfront for apps they had not tried. The apps that met a basic need in a well-executed way could find their audience without significant marketing investment.
Tag: sqlite
A Background Job Queue in One SQLite File Covers What Most Apps Deploy Redis For
A signup handler has to send a welcome email, and sending it inline puts a third-party API call inside your request. So you move it into a background job, and the usual next step is Redis, a client library, a worker process, a dashboard, and a note in the deploy docs about what happens to queued jobs when Redis restarts without persistence. If the app runs on one machine, you’ve added a second stateful service to look after a table’s worth of data.
A Single-File Log Database: Pipe Logs In, Query Them With SQL, Hand the File to Anyone
The incident is over, the postmortem is Thursday, and someone wants the logs from the bad three hours. You can attach a gzip nobody will open, paste a screenshot of a grep, or stand up a search cluster to answer one question. The question is usually “which paths returned 500, and when did it start”, which has a GROUP BY hiding in it, and a GROUP BY is where grep runs out. A full observability stack answers it, but that’s a heavy answer for a team that doesn’t already run one.
An Embedded Workflow Engine With Five Primitives: Trigger, Condition, Action, Wait and Retry
A user signs up on Monday. If they haven’t activated by Wednesday, you send a nudge email, and if the email provider times out, you try a few more times before flagging the account. That’s the whole spec. Most teams build it as a cron job that scans for users in the wrong state, a nullable nudge_sent_at column and a retry loop written late on a Friday. It holds until the cron overlaps itself, or a deploy lands mid-loop, or the provider times out after actually sending the message and one customer gets three emails.
Incremental View Maintenance Small Enough to Embed Turns Dashboard Queries Into Lookups
A dashboard tile shows today’s US traffic, so every page load runs SELECT count(*) FROM events WHERE country = 'US' over a table that grew by a few hundred thousand rows since yesterday. SQLite answers correctly. It also walks every matching index entry to do it, because its b-trees don’t keep counts, and it does the same walk for the next viewer and the one after. Between two page loads the answer moves by a handful of rows, yet each load pays for all of them.
Spreadsheet Recalculation Inside a Database: Derived Values That Track Their Own Dependencies
A line item’s quantity goes from 4 to 5. The order subtotal should change, and so should the tax, the order total, the customer’s lifetime value and the regional revenue figure on a dashboard. Which of those actually update depends on which code path made the edit, because each one gets recomputed somewhere different: the checkout handler, the invoice renderer, a nightly job, a SQL view somebody wrote for finance. Every copy of the formula is another chance for two screens to disagree.
SQL and Key-Value Over the Same Bytes: An Old Database Idea Worth Making Small
A sensor node writes a reading every few seconds. The firmware wants one thing from storage: put a record by key, get it back by key, as fast as the flash allows. The dashboard on the gateway wants something else, like average temperature by sensor by hour, joined to a table of sites. The usual answer is two databases with a translation job between them, a key-value store on the device and SQLite or Postgres upstream. Then comes a year of debugging the translation: a unit that changed, a row that arrived twice, a field the device encodes one way and the gateway reads another.
Store Changes Instead of Current Rows: An Embedded Database Built Around History
A support ticket asks two plain questions: which plan was customer 4411 on when the August invoice went out, and who moved them off it? The customers table can’t answer either. It holds today’s row. The audit table someone added two years ago holds most of the story, apart from the week a data fix ran a bulk UPDATE in raw SQL and skipped the ORM callbacks that write the audit rows.
Precomputing: Keeps Dashboard Answers Ready in a SQLite File as the Data Arrives
Most dashboards ask the same few questions all day long: requests per endpoint, month-to-date usage for one customer, error rates by status code. The usual setup recounts raw rows from scratch on every refresh, or ships every row to a hosted analytics service that bills by the gigabyte. A dashboard that needs to answer quickly on demand either waits for a database query to finish, or pays for a service that stores everything.
Building Offline-First Mobile Apps Is Harder Than It Looks and Worth It
The default architecture for most mobile applications treats network connectivity as a reliable precondition. API calls are made on demand. Failures produce error states. The user waits for responses. This architecture produces apps that work acceptably on fast, reliable connections and badly on slow, intermittent, or absent connections — which describes the conditions under which many mobile users actually use apps.
Offline-first architecture inverts this assumption. The app reads from and writes to local storage first. Network synchronization happens in the background, opportunistically, whenever connectivity permits. The user experience is fast and available regardless of network state. The complexity is in the synchronization layer, which most teams underestimate significantly before they build it.
Tag: startup ideas
40 Radically Different Infrastructure Primitives, From Reach and Expect to Ignorance and Stop
This list deliberately leaves “tiny version of Redis, Kafka or SQLite” territory behind. That was the first list of 20 primitives. The more interesting search space is a primitive that introduces a new operation, one developers might eventually feel should have existed all along. Some research paper or niche project has probably explored pieces of these. They’re meant as category-level concepts, not smaller copies of familiar products.
Forty primitives
1. Reach. Store a current state plus transition rules and continuously maintain which states are reachable from here: REACHABLE(current_state). A database answers what is; Reach answers what can happen. Uses: AI agent safety, workflows, infrastructure, manufacturing, cybersecurity attack paths.
Screening 20 Infrastructure Primitives Money First: Why Distill and Precomputing Survive
Run the 20 primitive project ideas through the four-question screen strictly and the ranking changes a lot. Several technically attractive ideas turn into weak projects. The economic buyer is unclear, free infrastructure already solves the problem well enough, or the moat amounts to “ours is smaller.”
So Statefile, Lease, BareQueue, TTL, Count, Remember, Freeze and probably ConfigLog go out at this stage. They all solve real engineering problems, but the money question is poor. Redis, SQLite, existing Go libraries, message queues, object storage, Git and cloud infrastructure already give acceptable answers. A tiny implementation might make a respectable GitHub project. “Simpler and smaller” doesn’t tell you who eventually writes a meaningful check.
Screening App Ideas Before You Write Code: Four Questions, Starting With Who Pays
App ideas cost nothing. Every one of them looks shippable in a weekend, and then the weekend turns into three months of auth flows, sync bugs, review notes and a paywall that took longer than the app.
So before Xcode or Android Studio opens, put the idea through four questions and write the answers down. Who pays? What problem does it solve? Can you say what it does in one sentence? Why would anyone switch, and what stops Apple from copying it? Ask them in that order. Money goes first because it kills weak ideas fastest, while a kill still costs an evening.
Nine Apps Worth Coding, and the Hard Part Buried in Each One
Every app idea has a boring 90% and a nasty 10%. The boring part is CRUD, auth, a settings page, Stripe. The nasty part is the one subsystem that decides whether the thing works at all, and it’s usually not the part that looks hard in the pitch. Below are nine builds worth attempting, with the nasty 10% named up front so you can decide whether you want to spend your weekends there.
Tag: state management
Debug From a Timeline of State Changes Instead of Ten Thousand Log Lines
A ticket comes in: order 8812 shows as cancelled, but the customer’s card was charged. You open log search. The checkout service wrote a couple of hundred lines for that request; the payment webhook handler wrote a few dozen; the job that expires unpaid orders wrote a line for every order it looked at that minute. The answer is in there somewhere. Forty minutes later you find it. The expiry job cancelled the order thirty seconds after checkout began, and the payment provider’s webhook landed half a second after that.
State Management in React Native Has Too Many Options and One Right Answer
The React Native state management ecosystem is the most frequently relitigated technical decision in mobile JavaScript development. Every twelve to eighteen months, a new library emerges, accumulates advocates, generates a wave of “why I switched from X to Y” blog posts, and joins the list of options that teams now have to evaluate. The list includes Redux, MobX, Zustand, Jotai, Recoil, TanStack Query, SWR, Context API, and several others with smaller followings. The churn produces the impression that state management is an unsolved problem requiring continuous reinvention.
Tag: swift
SwiftUI After Five Years: What Works and What Doesn't
SwiftUI launched in 2019 with a demonstration that made experienced iOS developers simultaneously excited and nervous. Excited because the declarative paradigm promised to eliminate the impedance mismatch between interface builder storyboards and code. Nervous because Apple’s track record with new frameworks included several that were replaced, deprecated, or quietly ignored within a few development cycles.
Five years later, SwiftUI is neither the complete replacement for UIKit that Apple’s marketing implied nor the abandoned experiment that skeptics predicted. It is a mature but still-evolving framework that handles a large majority of common iOS UI requirements elegantly, struggles with a specific set of advanced requirements, and has permanently changed how iOS UI code is written even when developers reach for UIKit to solve problems SwiftUI cannot.
Swift vs Kotlin: The State of Native Mobile Development in 2026
The question of whether to build natively for iOS and Android or to abstract across both platforms with a cross-platform framework has occupied mobile development teams for more than a decade. The answer has not settled. What has settled is the character of native development itself — and in 2026, Swift and Kotlin have each reached a maturity that makes the native argument significantly stronger than it was five years ago.
Tag: testing
Give Every Database Query a Budget and Fail the Build When It Scans Too Much
A developer changes a login lookup to WHERE lower(email) = lower($1) so that sign-in stops being case-sensitive. Every test passes. The btree index on email can’t serve a query that wraps the column in a function, so Postgres reads the whole users table, and on a test database with forty rows that’s the cheapest plan anyway. The change ships. A week later someone notices login latency tracking the signup count. The fix is a one-line expression index that would have taken a minute if anything had objected during review.
Testing Mobile Apps at Scale Without Losing Your Mind
Mobile testing is harder than web testing for reasons that are partly technical and partly organizational. The technical reasons: the diversity of physical devices, OS versions, screen sizes, and hardware configurations that a production mobile app must run on is several orders of magnitude larger than the browser matrix that web applications face. The organizational reasons: mobile development cycles historically moved faster than testing infrastructure could keep pace with, producing teams that ship without adequate test coverage and accumulate testing debt that compounds with each release.
Tag: ui frameworks
Jetpack Compose Is Winning Android UI Development
Google’s transition of Android UI development from the XML layout system to Jetpack Compose has been, by the standards of platform UI framework migrations, unusually smooth. Compose became stable in August 2021. By 2024, it was the recommended approach for new Android development. In 2026, the question for Android teams is no longer whether to adopt Compose but how to manage the migration of existing View-based codebases.
The comparison with SwiftUI is instructive. Both frameworks launched within two years of each other, both represent declarative replacements for older imperative UI systems, and both have faced criticism for gaps between their initial capabilities and the full feature set of what they replaced. Compose has navigated this transition with fewer of the minimum-API-level constraints that limit SwiftUI’s adoption curve, because Android’s broader device compatibility requirements have historically pushed Google toward more conservative backward compatibility policies.
SwiftUI After Five Years: What Works and What Doesn't
SwiftUI launched in 2019 with a demonstration that made experienced iOS developers simultaneously excited and nervous. Excited because the declarative paradigm promised to eliminate the impedance mismatch between interface builder storyboards and code. Nervous because Apple’s track record with new frameworks included several that were replaced, deprecated, or quietly ignored within a few development cycles.
Five years later, SwiftUI is neither the complete replacement for UIKit that Apple’s marketing implied nor the abandoned experiment that skeptics predicted. It is a mature but still-evolving framework that handles a large majority of common iOS UI requirements elegantly, struggles with a specific set of advanced requirements, and has permanently changed how iOS UI code is written even when developers reach for UIKit to solve problems SwiftUI cannot.
Flutter's Bet on a Single Codebase Has Mostly Paid Off
Google’s decision to build Flutter on top of Dart — a language that had minimal developer mindshare and an uncertain future when Flutter launched — was a risk that the broader developer community viewed with skepticism. Dart was not JavaScript. It was not Kotlin. It was not a language that developers had strong feelings about because most developers had never used it. Building a cross-platform UI framework on an obscure language was, on its face, an unusual strategic choice.
Tag: ux
Push Notifications Have a Spam Problem That Developers Built
Push notifications were introduced as a mechanism for delivering timely, relevant information to mobile users. They have become, in the hands of most apps, a mechanism for re-engaging users who have stopped using an app — delivered at volumes and frequencies that have trained users to disable notifications as a reflex rather than a deliberate choice.
The data on notification effectiveness tells a story that most growth teams choose not to hear. Opt-in rates for push notifications have declined steadily as users have learned from experience what push permission grants apps permission to do. iOS’s explicit permission prompt — which apps must request before sending any notification — shows opt-in rates below 50 percent for most app categories. Users who do opt in disable notifications at rates that correlate directly with how many notifications an app sends, not with how relevant those notifications are.