Writing

Shipping Real Platforms with SvelteKit, TypeScript, and PostgreSQL

Most platforms I build at Kenvin — Cezve, Darmanjo, MKPower, Panah Ceram, CopyPasta, 118x — share one backbone: SvelteKit, TypeScript, Drizzle over PostgreSQL, deployed on Vercel. Here is why that stack won, and what production Persian-first products taught me.

One backbone behind most of my recent platforms

Look at the platforms I have shipped recently at Kenvin and a pattern repeats. Cezve runs cafes end to end. Darmanjo runs a wound-care clinic. MKPower sells engine parts by part number, Panah Ceram is a fixtures catalog, CopyPasta shares text and code, and 118x gives local businesses a page of their own. Different businesses, same backbone: SvelteKit and TypeScript, a PostgreSQL data layer through Drizzle ORM, Tailwind interfaces, deployed on Vercel. This article is why that stack earned the repetition.

A shared backbone is a deliberate trade. I give up per-project novelty and gain something more valuable for a small studio: every hard lesson — auth, uploads, rate limits, admin editing, Persian typography, deployment — is learned once and then inherited by the next product instead of re-bought at full price.

Why SvelteKit fits product work

Product work is mostly forms, lists, permissions, files, and money. SvelteKit’s model maps to that reality cleanly: server-rendered pages by default, form actions and load functions close to the route they serve, and TypeScript types flowing from the database schema to the component without a hand-written API layer in between. The result is one codebase where the distance between “the cafe owner needs X” and shipped X stays short — which, for the kind of platforms I build, matters more than any framework benchmark.

Svelte itself helps by staying out of the way. Components read like the HTML they produce, reactivity is explicit, and the compiled output keeps pages light for users on ordinary phones and ordinary connections — which describes most of the people scanning a cafe’s QR code or checking a part price from a workshop.

Drizzle and PostgreSQL: boring in the best way

Underneath, these platforms sit on PostgreSQL with Drizzle as the query and schema layer. I have written before about respecting the database; Drizzle suits that mindset because the SQL stays visible. Queries look like what they execute, schemas are TypeScript, and when a page is slow I can reason about the actual query instead of decoding ORM behaviour. Where the deployment shape calls for it, that PostgreSQL runs on Neon — MKPower and Panah Ceram do — without changing how the code reads.

The honest summary of my database philosophy after Jajiga and these platforms: pick the relational database, model the data plainly, index what the product actually queries, and keep one obvious place where queries live. Exotic data layers are a tax every future feature pays.

Persian-first products and real users

Most of these platforms are Persian-first and right-to-left, and that is an engineering constraint, not a coat of paint. Cezve’s panel is Persian and RTL end to end because cafe staff work in Persian; Darmanjo combines Persian content with Paraglide-powered multilingual structure; MKPower has to make a part number findable by a mechanic who types it from a workshop note. Numbers, dates, money, search behaviour, even which side a table’s QR code flow starts from — language reaches all of it.

Building this way changed my defaults. I treat Persian typography (Vazirmatn everywhere), Jalali-aware presentation, and mixed-direction content — a Latin part number inside a Persian sentence — as day-one concerns. Retrofitting RTL onto a finished product is five times the work of designing with it, and users can always tell which one you did.

The details that compound

A backbone is also where small decisions compound. Uploads go to S3-compatible storage with presigned URLs instead of through the app server. Admins edit content in Tiptap instead of me hand-editing database rows. MKPower uses tRPC and Upstash-backed rate limiting where its catalog traffic justifies it; CopyPasta deliberately uses almost nothing beyond SvelteKit and Postgres because the product is a single sharp tool. Same backbone, different weight per product — the stack bends without breaking.

Deployment compounds too. One adapter, one hosting shape, preview deployments per branch, and the same operational instincts across six products. When something misbehaves at 9 p.m. in one platform, I have usually already met that class of problem in another. That familiarity is an operational feature no framework comparison table will ever show you.

Performance and discovery matter to these businesses in the same practical way. Public pages — a clinic’s services, a catalog of sanitary ware, a local business’s page on 118x — must render fast and read clearly to search engines and answer engines, so server rendering and prerendering are defaults, with client-side richness added where the product actually needs it: the cafe’s live panel, the parts search, the paste viewer. On this very site that discipline goes furthest: every page is prerendered, both languages, with structured data and plain-text editions generated from the same content. Speed is rarely about heroic optimization; it is about not shipping weight the page never needed, and about measuring on the kind of phone and connection the actual customer holds rather than the machine on my desk.

What I watch out for

No stack is free. SvelteKit’s ecosystem is younger than React’s, so some integrations are build-it-yourself territory — my Yoshi framework work on SvelteKit exists partly to smooth exactly those edges. Serverless deployment punishes chatty database access, so query discipline matters from the first feature. And a shared backbone only pays off if you resist forking it per project until the “shared” part is theoretical.

Even with those costs named, this is the stack I would choose again for product platforms today, because it has carried six of them — plus this website — from brief to production with the same small set of ideas. If you are planning a platform and want it built on something proven rather than fashionable, my résumé is the place to start.

All writing