Tech Stack
Technologies and tools I use
26
Total technologies
7
Categories
Frontend
Primary track
TypeScript
Use discriminated unions and satisfies to encode domain rules in the type layer.
Preparing code walkthrough…
const tech = {
name: 'React',
category: ['Frameworks & Libraries'],
beforeCode: 'const count = 0',
afterCode: 'const [count] = useState(0)',
};What changed
Moves from a loose object literal to a discriminated union (kind: 'code' | 'narrative') verified with satisfies — TypeScript catches missing fields at the definition site, not at the call site.
Languages
Core programming languages used in product delivery and frontend systems.
TypeScript
HTML
TypeScript
Use discriminated unions and satisfies to encode domain rules in the type layer.
Preparing code walkthrough…
const tech = {
name: 'React',
category: ['Frameworks & Libraries'],
beforeCode: 'const count = 0',
afterCode: 'const [count] = useState(0)',
};What changed
Moves from a loose object literal to a discriminated union (kind: 'code' | 'narrative') verified with satisfies — TypeScript catches missing fields at the definition site, not at the call site.
Frameworks & Libraries
Framework and state patterns for scalable interfaces.
React
Next.js
SvelteKit
Express.js
Elysia.js
Web Component
TanStack Query
XState
React
Replace manual loading state with React 19's built-in action model.
Preparing code walkthrough…
function CheckoutButton({ items }) {
const [loading, setLoading] = useState(false);
async function handleClick() {
setLoading(true);
await fetch('/api/checkout', {
method: 'POST',
body: JSON.stringify(items),
});
setLoading(false);
}
return <button onClick={handleClick}>Buy</button>;
}What changed
Moves from ad-hoc useState flags to useActionState — the form's action prop drives the async lifecycle, isPending replaces manual toggles, and success callbacks compose cleanly.
Database
Data layer technologies used for product persistence and analytics.
MySQL
MongoDB
Supabase
Prisma
PostgreSQL
Supabase
BaaS speed with full Postgres control — auth, real-time, and RLS in one platform.
Explanation-only walkthrough
I reach for Supabase when I need to prototype at BaaS speed without giving up Postgres depth. Row Level Security encodes authorization rules inside the database itself — keeping API routes thin and access policies version-controlled. The real-time layer replaces polling with a WebSocket push channel, a natural fit for collaborative or live-updating surfaces. Supabase's auto-generated REST and typed client mean the schema becomes the contract, and breaking changes surface at build time rather than in production.
What changed
Moves authorization out of application code and into Row Level Security policies at the database layer, reducing surface area for bugs and making access rules auditable alongside the schema.
Styling
Design-system and styling approaches for maintainable UI.
CSS
Vanilla Extract
Tailwind CSS
StyleX
Testing
Quality and confidence tooling for stable releases.
Storybook
Playwright
Playwright
Structure tests as readable steps, not a flat sequence of awaits.
Preparing code walkthrough…
test('tech stack page', async ({ page }) => {
await page.goto('/en/tech-stack');
});What changed
Moves from a single navigation to named test.step blocks — each assertion is scoped, failures point to the broken step, and the test report reads like a product spec.
Tools
Execution environment and collaboration tools used daily.
Bun.js
Github
Command Line
Figma
Storybook
Playwright
Playwright
Structure tests as readable steps, not a flat sequence of awaits.
Preparing code walkthrough…
test('tech stack page', async ({ page }) => {
await page.goto('/en/tech-stack');
});What changed
Moves from a single navigation to named test.step blocks — each assertion is scoped, failures point to the broken step, and the test report reads like a product spec.
Backend
Server and platform technologies used in full-stack delivery.
Next.js
SvelteKit
Express.js
Elysia.js
Supabase
Prisma
PostgreSQL
Next.js
Use PageProps and async params to keep the route server-first with full type safety.
Preparing code walkthrough…
"use client";
export default function TechStackPage() {
const [selected, setSelected] = useState('React');
return <TechStackExperience selected={selected} />;
}What changed
Moves from a client-heavy page shell to an async Server Component typed with PageProps<'/route'> — the globally available helper generated by next typegen that resolves params as a Promise and eliminates manual type annotations.
How I apply this stack
I optimize for predictable delivery: clear architecture, reusable design systems, measurable performance, and collaboration-friendly code.