Developers

Engineering write-ups on how Storyie is built — architecture, tooling, and code.

Entitlements Need Plan and Status

Storyie Engineering Team5 min read

Checking only plan name or only status made the same user Pro in one feature and Free in another. isProEntitled(plan, status) is the fix.

Soft Deletes Are an API Contract

Storyie Engineering Team5 min read

Soft delete on the server is only half the story. The sync pull contract must carry tombstones as typed delete changes — not omit the row and hope clients notice.

Exponential Backoff That Survives App Restarts

Storyie Engineering Team6 min read

In-memory retry timers forget their schedule when the OS kills the app. Storyie stores the backoff deadline in SQLite so the next launch picks up exactly where the last attempt left off.

Designing an Offline Mutation Queue on SQLite

Storyie Engineering Team7 min read

An offline edit is a promise the app has to keep after a force-quit. Storyie persists every pending mutation as a SQLite row with a status state machine, exponential-backoff retry, and an ownership guard against stale server data.

Lexical JSON to Markdown Without a Browser

Storyie Engineering Team8 min read

The canonical Lexical-to-Markdown path needs a live editor and a registered node for every type. Our export runs in a Lambda, so it walks the JSON tree directly instead.

UTC Month Boundaries for Subscription Quotas

Storyie Engineering Team8 min read

Our free plan allows 31 diaries a month. When "a month" was UTC in one place and local time in another, the reset and the dedup key disagreed at midnight on the 1st. Here is the fix.

Last-Write-Wins Is a Product Decision

Storyie Engineering Team8 min read

LWW is not "give up and take the newest timestamp." Storyie forgives one second of clock drift, breaks ties toward the server, guards uncommitted local edits at the SQLite layer, and always tells you when your version was replaced.

Migrating Authentication Without Rewriting Every Caller

Storyie Engineering Team7 min read

A provider swap touches every page that reads the current user. We contained the blast radius to a single file — a CompatUser shim — instead of a 56-file rewrite. The trade-off: the shim tells one deliberate lie.

SST v3 tips: Pulumi Output, Cron, ARM64

Storyie Engineering Team8 min read

Six months of running Storyie on SST v3 produced a list of things the docs don't cover — Pulumi Output resolution in transforms, stage-scoped env loading, Cron offsets to avoid connection pool contention, and more.

Deploy Next.js to AWS with SST v3 (not Vercel)

Storyie Engineering Team8 min read

We run Storyie on AWS instead of Vercel — not out of stubbornness, but because SST gives us fine-grained CloudFront control, cheap Lambda cron jobs, and multi-tenant wildcard domains that Vercel can't match without a painful price tag.

Drizzle migrate and custom migrations on Supabase

Storyie Engineering Team8 min read

After a year of shipping Storyie, our migration file count hit 56. Here is what we learned about running Drizzle ORM in production with Supabase — two-stage CI deployment, when to write custom SQL, and how we think about rollbacks.

Drizzle ORM schema design with Supabase Postgres

Storyie Engineering Team9 min read

Database schemas are the foundation of any application, yet they're often the source of the most frustrating bugs: runtime errors from typos in column names, incorrect types passed to queries, and subtle data inconsistencies that slip through testing. At Storyie, we eliminated these issues by...

How to serialize Lexical EditorState to JSON

Storyie Engineering Team17 min read

Building a Lexical editor that works identically on web and mobile is one of the most challenging aspects of cross-platform development. At Storyie, diary entries created on our Next.js web app must render perfectly in our React Native mobile app, and vice versa. Through a two-package architecture...

Expo SDK 53 + React Native 0.79: Cross-Platform Mobile Setup

Storyie Engineering Team7 min read

Mobile app development has come a long way from writing separate codebases for iOS and Android. At Storyie, we chose Expo SDK 53 and React Native 0.79 to build a production-ready mobile app that shares code with our Next.js web application while delivering a native mobile experience. In this post,...