Posts
Thoughts, learnings, and snippets from the journey back to dev.
Algorithms Aren't Working for Me — An Anti-Algorithm Manifesto
From dating apps to social feeds, what algorithms actually optimize for isn't my life — it's my time on the app
Deploying a Free pages.dev Domain on Cloudflare Pages — How to Avoid the Workers Screen Bait-and-Switch
Click Create application and you get a Worker creation screen, not Pages. The full process of hunting down the hidden Pages entry point and shipping a static Next.js site on a free domain
I Built My Own Ad-Free, Payment-Free Playground for My Kids — Kiosk Mode on the Web
An old MacBook, turned into a dedicated kids device with a web app I wrote myself — entering fullscreen, a parent lock, and a time limit, all built with nothing but browser APIs
And Just Like That, Fable 5 Was Gone — Vanished at 3 AM
How the Fable 5 model I happily used on the Pro plan suddenly disappeared from my usage list one night, replaced by a credits-required message
Syncing Obsidian on Mobile via Git Was Too Painful, So I Built My Own Note App (RepoNote Dev Log)
Git on mobile Obsidian was complex and conflict resolution unbearable, so I built a Flutter note app that auto-syncs with a GitHub repo — including the part where I built it in React Native first and threw it out
Editing Video from Just YouTube Links — A Next.js + FastAPI + yt-dlp + FFmpeg Dev Log
What I learned building a personal web editor that pastes a YouTube link, lets you pick segments, and stitches them into one MP4
The Fable 5 Rollercoaster — Blocked, Then I Thought It Was Over, Then Extended
Fable 5 got blocked by a US government request, then I used it like crazy up to the last day before the switch to pay-per-use, thought it was over, and then it got extended — a month-long log
Get $100 in free ChatGPT credits.
Get free ChatGPT credits.
Solo SaaS Payments — Starting With Stripe, Ending Up on Paddle
How I finished wiring Stripe subscriptions into MatchDa, only to discover four days later that the account country itself made the whole setup unsustainable — and the technical lessons from migrating to Paddle (Merchant of Record)
Flutter 앱에 구글 애드몹(AdMob) 붙이는 법 — 애드센스와 헷갈리지 않기
Flutter 앱에 google_mobile_ads로 배너·전면·보상형 광고를 연동하는 방법과, 붙이기 전에 반드시 점검해야 할 것들 정리
개인 프로젝트 GitHub에 올리기 전, 로그인 쿠키까지 털리지 않으려면 — 저장소 보안 점검 체크리스트
브라우저 자동화 프로젝트를 GitHub에 올리기 전에 실제로 진행한 시크릿 검사, 개인정보 플레이스홀더 처리, 안전한 초기 커밋 과정을 단계별로 정리
AI 디자인 핸드오프를 코드로 옮기며 배운 것들 — 모노크롬 디자인 시스템, Tailwind 토큰 함정, 트렌딩 알고리즘
HTML 디자인 핸드오프 재구현부터 Tailwind 4 @theme inline 함정, 중복 CTA 정리, Wikimedia 이미지 시드까지 — 사이드 프로젝트 리뉴얼 하루의 기록
노가리 개발기 — 익명 커뮤니티 플랫폼을 하루 만에 기획부터 배포까지
Next.js 16 + Supabase + Claude API로 집단지성 기반 익명 커뮤니티 '노가리'를 만들면서 겪은 설계 결정과 시행착오 정리
블로그 발행을 자동화해보자 (11) 아침 9시에 아무 일도 일어나지 않았다 — 롤백의 후유증과 세션 연명 cron
분명히 등록해둔 Vercel Cron이 조용히 안 돌았던 원인(rollback 후유증)과, 하루도 못 버티고 죽는 카카오 세션을 비밀번호 저장 없이 연명시키는 keep-alive cron 설계
Flutter 게임에 서버 없이 멀티플레이 넣기 — LAN 소켓, UDP 방 찾기, 자동 재접속까지
심플 마작 게임에 외부 서버 없이 같은 Wi-Fi 멀티플레이를 붙인 과정 — 호스트 권한 구조, UDP 브로드캐스트 방 발견, 좌석 회전 트릭, 실기기에서 만난 끊김 문제와 자동 재접속 해결기
멀티플레이 게임은 침묵이 버그다 — 플레이테스트에서 배운 대기 상태 UX
폰 3대로 가족과 마작 게임을 플레이테스트하며 발견한 멀티플레이 특유의 UX 문제들 — 응답 제한시간의 이중 강제, 선택 중 상태 공유, 퇴장/복귀 알림을 Flutter로 해결한 기록
Flutter 마작 게임에 점수제와 효과음 넣기 — 영수증 연출과 WAV 직접 합성까지
심플 마작 게임에 아이도 이해하는 보너스 점수제를 설계하고, 외부 에셋 없이 파이썬으로 효과음을 합성해 audioplayers로 재생한 과정 정리
주사위 4개로 미식축구를 재현하다 — 보드게임 Playbook Football 이야기
Flutter 앱으로 구현 중인 보드게임 Playbook Football의 원작 소개와, 주사위 4개 + 카드 차트로 굴러가는 판정 시스템을 뜯어본다
보드게임 규칙서 PDF 한 권으로 Flutter 풋볼 게임 만들기
미국 풋볼 보드게임 Playbook Football의 규칙서와 카드를 분석해 주사위·카드 차트 기반 AI 대전 모바일 게임으로 옮긴 과정
Flutter 보드게임 앱에 하루 만에 붙인 5가지 — 애니메이션, 다국어, 로컬 멀티플레이까지
Playbook Football Flutter 앱에 주사위 애니메이션, 한/영 다국어, 같은 Wi-Fi 멀티플레이, 앱 아이콘 생성까지 하루 동안 붙인 기능들의 구현 기록
Building a Prescription Fraud-Verification Blockchain With an AI Coding Assistant (From Smart Contract to Web UI)
A record of recording prescription hashes on-chain with a Solidity smart contract, going from a local demo to a Sepolia testnet deployment and a web UI, all in one day
카세트 앱에 유튜브 링크를 붙이려다가 — WebView 브릿지와 씨름한 기록
친구와 테이프를 만들어 주고받던 추억을 다시 만들고 싶어서, 스킵 없는 레트로 카세트 뮤직 플레이어에 유튜브 링크 추가와 테이프 공유 기능을 붙이며 react-native-youtube-iframe의 postMessage 브릿지 유실 버그와 FF/REW seek 레이스 컨디션을 실기기 로그로 잡아낸 과정
Claude Code가 매번 물어보지 않게 하려면 -- dangerously-skip-permissions 파헤치기
Claude Code의 --dangerously-skip-permissions 플래그가 뭘 하는지, 왜 위험한지, 그리고 안 물어보게 하면서도 안전하게 쓰는 대안까지 직접 써보고 정리했다
15년 된 안드로이드 게임을 되살려보기 (1) — APK 리버싱으로 진짜 범인 찾기
2011년에 나온 유니티 기반 안드로이드 게임이 요즘 폰에서 실행되자마자 꺼지는 이유를, androguard와 apktool로 APK를 뜯어보며 추적해 Google Play 라이선스 체크가 범인이라는 걸 찾아낸 과정
15년 된 안드로이드 게임을 되살려보기 (2) — 세 겹의 벽을 만나고, 결국 새로 만들기로 했다
2011년 유니티 게임의 라이선스 체크를 패치해 재서명까지 성공했지만 최신폰에서 세 겹의 네이티브 벽에 막혀 실행에 실패하고, 결국 분석한 게임 구성을 바탕으로 Flutter로 고스톱을 새로 만들어 갤럭시 S24 FE에서 구동에 성공한 기록
Mahjong Joy 개발기 (1) — 마작에서 족보를 빼면 게임이 될까? 기획 분석과 작업 계획
마작의 족보를 전부 걷어내고 3-3-3-3-2 짝맞추기만 남긴 캐주얼 게임을 Claude Code와 함께 기획 문서 분석부터 시작한 기록
Mahjong Joy 개발기 (2) — 마작 승리 판정 알고리즘, 재귀로 뚫기
14장의 패가 몸통 4개와 머리 1쌍으로 분해되는지 판정하는 재귀 알고리즘을 Dart로 구현하고 단위 테스트로 함정 케이스까지 잡은 과정
Mahjong Joy 개발기 (3) — 게임 엔진과 AI, 그리고 100판 자동 대국 테스트
4인 마작 턴 루프를 상태 머신 엔진으로 설계하고, 휴리스틱 AI 3명을 붙여 100판 자동 대국 시뮬레이션으로 검증한 과정
Mahjong Joy 개발기 (4) — 파스텔 UI와 RotatedBox 마작 테이블, 타일 애니메이션
Flame 없이 순수 Flutter 위젯으로 파스텔톤 마작 UI를 만들고, RotatedBox 4방향 테이블 배치와 TweenAnimationBuilder 타일 애니메이션을 구현한 과정
Mahjong Joy 개발기 (5·완) — 점수 시스템과 메인화면으로 게임 완성하기
론 방총 전액 지불과 츠모 분담이라는 마작식 점수 구조를 족보 없이 이식하고, 메인화면과 게임 설명서까지 붙여 게임을 완성한 시리즈 마지막 편
Next.js로 SEO 기본기 세팅하기 — robots, sitemap, OG 이미지까지 코드로
로그인 위주 서비스에서 SEO 작업 범위를 공개 페이지로 좁히고, robots.txt·sitemap.xml·OG 이미지를 Next.js 파일 컨벤션으로 세팅하다가 미들웨어가 이 파일들을 전부 막고 있던 버그까지 잡은 기록
[Pixel Village Part 1] Building an RPG Village Inside a Blog — Three.js 2D Top-Down Setup
The first step in building a 90s-RPG-style top-down village in a Next.js blog with Three.js OrthographicCamera — keyboard movement, AABB collision, and camera tracking
[Pixel Village Part 2] Drawing Pixel Art in Code, With Zero Image Files
How to define sprites as ASCII strings, draw them onto a canvas, and use them as Three.js textures — NearestFilter, a 3x5 pixel font, and Y-sorting
[Pixel Village Part 3] Opening the Library Door — Scene Transitions and Blog Data Integration
Fade transitions for entering buildings, preventing an infinite back-and-forth loop, and stocking the library bookshelf with real blog posts based on tags
[Pixel Village Part 4] A Guestbook That Grows Into Trees — a GitHub JSON Store and 288 Faces
A guestbook easter egg where writing on a stone tablet plants a tree with a face somewhere in the grass. Storing it via GitHub commits with no DB, blocking spam, and giving each tree a random face
Showing a Game Overlay on the Home Screen — Once Per Session, So It Doesn't Get Annoying
How to show a pixel game as a full-screen overlay on the blog's first visit to home, without annoying repeat visitors, using sessionStorage, and a stacking-context bug where the X button got hidden behind the Nav
Automating Blog Publishing (10): When You Need to Log Into Someone Else's Account — Why I Chose Browserbase, and How to Actually Use It
Why I chose Browserbase as the way to connect someone else's Tistory/Naver account without our code ever touching their password, and the actual integration code from session creation to login detection
Automating Blog Publishing (8): The Time Deploying Monetization Code Nearly Killed Auto-Publishing, Silently
During a multi-tenant conversion turning a personal tool into a monthly-subscription SaaS, a single deploy nearly stopped daily auto-publishing with nobody noticing — and the recovery that followed
Automating Blog Publishing (9): <dialog open> Isn't a Modal — And the Deploy URL That Wouldn't Update
Why a native dialog tag with only the open attribute doesn't become a real modal, and a deployment-alias problem where the same project showed an old screen depending on which URL you visited
Landing a Job in Deep Learning & Big Data — What a Developer Should Nail Down in 6 Months
A portfolio beats finishing every course. A learning roadmap for deep learning and big data, organized by job role, aimed squarely at getting hired
Two Different AI Functions Were Writing Resumes in the Same Service — One Better Than the Other
Following up on a user's subtle quality-comparison feedback led to discovering a duplicated resume-generation API, unified by porting the RAG and prompt techniques, and cleaning up the redundant buttons
Building My Own Local LLM — A Realistic Way to Run Sonnet-Level Performance on My Mac
Can an individual actually build an LLM? A rundown of realistic options — from running open-weight models, to RAG, LoRA fine-tuning, and training nanoGPT
It's Definitely Saved in the DB, But Not on Screen — the Trap useState's Initial Value Sets
How I tracked down and fixed a common React bug — a component that copied server data into local state for drag-and-drop, then kept ignoring fresh data the server sent down afterward
Search Console's Excluded-From-Index Report — Not Everything Needs Fixing
Diagnosing 7 exclusion categories on a multilingual Next.js blog's Search Console report, one by one, separating what needs fixing from what should be left alone
I Told the AI to "Pretend You're a Job Seeker and Try It" — It Caught a Real Bug
Creating a fictional job-seeker persona and driving it through a headless browser from signup all the way to RAG tailored-resume generation, and how I fixed the AI fact-fabrication bug found along the way
Getting a Free support@yourdomain.com Email With ImprovMX
How to forward custom-domain email to a personal Gmail account for free, and even send from that address, without a paid mailbox
Workspace Upgrades (1): The Problem of Company Names Getting Cut Off in Kanban Cards
Fixing a kanban card layout where the status dropdown and the company name were fighting for space on the same line, by moving the status badge down to its own row
Workspace Upgrades (2): Making the "AI Analysis" Button Actually Write the Resume
Turning a button that only compared a job posting against a resume into one that directly rewrites the resume to fit the posting, redesigned as a clean 2-stage (analyze → translate) flow
Workspace Upgrades (3): The Bug Where the Korean Name Showed on the English Resume, and Adding Contact Fields
Fixing a Korean-name-exposure bug caused by a single English-translation prompt rule, and adding editable phone number and portfolio link fields to the resume contact line
Workspace Upgrades (4): Adding Kanban Card Drag-and-Drop With dnd-kit
Using dnd-kit, which was already installed but unused, to let dragging a kanban card between columns change its application status — and making sure clicks and drags never conflict
3 KakaoTalk Screenshots Uncovered a Hidden Bug Spread Across the Entire Service
Following up on a small UI bug report from a real-device mobile screenshot led to discovering — and fixing — a root-cause bug where Claude thinking-response handling was done wrong in 20 different places
Paddle Domain Review: Matchida (Typeform Survey) Answer Guide
Paddle Instead of Stripe for SaaS Payment Systems... Guide to Answering the Paddle Survey
Automating Blog Publishing — Building a Personal Automation Platform for Tistory and Naver (1) Overall Architecture
The story of designing, from scratch, a personal blog automation tool that writes an AI draft the moment you register a topic and publishes it via browser automation
Automating Blog Publishing (2): Auto-Generating Drafts in My Own Style With the Claude API
How a single style-guide document made the Claude API write blog drafts in my own voice every time, and the fallback path that let it run without an API key
Automating Blog Publishing (3): Auto-Publishing to Tistory With Playwright — A Story of Failing Three Times
A record of actually fixing a Tistory login session that kept disappearing, and a publish failure caused by grabbing the wrong markdown editor selector
Automating Blog Publishing (4): Building a Local Web Dashboard With No Framework
Building a local dashboard that handles topic registration, draft review, and publishing using nothing but Node.js's built-in http module, and why I chose not to deploy it to the cloud
Automating Blog Publishing (5): Taking a Local Tool to the Cloud — Vercel Blob Betrayed Me
The story of eventually putting a tool on Vercel that I had concluded a local dashboard was good enough for, and switching to Upstash Redis after running into Vercel Blob eventual-consistency problems
Automating Blog Publishing (6): Why Only the Title Went Up and the Body Vanished — The Trap CodeMirror Was Hiding
Tracing and fixing a bug where the publish log looked fine and the RSS title looked fine, but the actual post body kept coming out empty — viewed through the lens of CodeMirror and React state synchronization
Automating Blog Publishing (7): Assigning a Category to Auto-Published Posts
How I dug into the actual structure of Tistory's category-selection dropdown and attached auto-selection logic, to fix posts that kept going up with no category assigned
Hardening MatchDa (1): The Audit That Started With "Check If There Are Any Security Problems"
A security audit log covering a missing-auth API route, a cross-user delete bug, and a plaintext password sitting in a public repo — all found by sweeping the whole service
Hardening MatchDa (2): Completely Erasing a Password From History With git-filter-repo
A record of using git-filter-repo to substitute a plaintext password out of an entire commit history in a public GitHub repo, all the way through to a force-push
Hardening MatchDa (3): Merging 15 Migrations Into One schema.sql and Verifying It
Consolidating a fragmented set of Supabase migration files into a single schema file, and automatically cross-checking it column-by-column against the actual production DB via the PostgREST API
Hardening MatchDa (4): Designing a Viral Loop With a Public Resume-Sharing Link
Building a resume-sharing page viewable without login (/r/slug), designed with privacy protection and search-engine deindexing in mind from the start
Hardening MatchDa (5): Only One Education Entry Ever Showed — The Type Design Was the Problem
Tracing a bug where a resume always showed only one education entry, and finding the cause was a type designed as a single object instead of an array
Why We're Returning to a Strategy of Reducing the Number of Tokens
AI ultimately moves at the pace of humans.
Claude Fable 5: Resumes After an 18-Day Hiatus; “Free Credits” Period Runs Until 3:59 p.m. on July 8 (KST) – Including Strategies for Generating Codes
Clog Fable 5: Review and Future Usage Tips
Building a SaaS With an AI Coding Assistant (10): From Forgot Password to the Eye Icon — Closing Out Auth UX
The truth behind Supabase deliberately responding "as if successful" to a signUp for an already-registered email (an empty identities array), a one-line next-parameter design that blocks open redirects, and how I knowingly dodged this time the exact admin API trap that caused the data-loss incident in Part 2
Building a SaaS With an AI Coding Assistant (11): "Confirm Your Signup" Is Too Bland — Branded Emails and Resend SMTP
Two email HTML templates built back in table-layout-and-inline-styles style, an unexpected Mailgun MX record discovered via dig, a 401 scare from a send-only restricted key — the story of replacing Supabase's default auth emails with branded ones and wiring up Resend SMTP
Building a SaaS With an AI Coding Assistant (12): Where Does support@matchda.com Actually Go? — Building Domain Email Receiving
A dead Mailgun MX record exposed by dig, the twist of "oh...no Mailgun...and it costs money...", ImprovMX forwarding wrapped up with zero lines of code — the infrastructure detective story of turning support@matchda.com, which had only ever existed in a policy document, into an address that actually receives mail
Building a SaaS With an AI Coding Assistant (1): Rebuilding the URL Structure From Scratch
How I cleaned up MatchDa's tangled URL structure and redesigned the discover/applications flow off a single piece of user feedback
Building a SaaS With an AI Coding Assistant (2): The Day the AI Deleted My Account
An incident where a hidden filter bug in the Supabase admin API led my AI coding assistant to delete a real user account, and the DB safety rules I put in place afterward
Building a SaaS With an AI Coding Assistant (3): A RAG Tailored Resume, Built Without Embeddings
From auto-analyzing an uploaded resume file, to a RAG-style tailored resume implemented with nothing but keyword overlap and no extra infrastructure, to DOCX/PDF downloads that keep the on-screen formatting
Building a SaaS With an AI Coding Assistant (4): One-Click Collection, a Chatbot, and Going Paid for the First Time
One-click collection of big-name job postings verified against public ATS APIs, a support chatbot that only explains how to use the product, and turning a free SaaS into a paid one with Stripe subscriptions
Building a SaaS With an AI Coding Assistant (6): A Logo Mismatch, Managing 171 Postings, and Ctrl+A-Paste Analysis
Fixing a brand mismatch where the favicon and the in-app logo differed, the management problems that emerged once collected postings ballooned to 171 (edit mode, unscored filter), and AI analysis of a pasted-in full job description for sites where scraping fails
Building a SaaS With an AI Coding Assistant (7): Turning a Design Handoff File Into a Landing Page Demo Showcase
How I added three demo showcases (resume translation, job discovery, applications kanban) that reproduce actual product screens on a landing page that had only ever had a hero and feature cards — the story of a dormant design handoff file getting a second life as a marketing asset
Building a SaaS With an AI Coding Assistant (8): Killing Dead Links — Making Every Click on the Landing Page Go Somewhere
The landing page looked convincing with demo showcases, but actually clicking through it revealed holes everywhere — wiring the hero search to job discovery, opening the pricing page to logged-out visitors, and adding a new about page so all 4 header nav items finally worked
Building a SaaS With an AI Coding Assistant (9): The "Grown-Up" Parts of a SaaS — Settings and Legal Documents
How I wired up a settings page, password change, terms of service, privacy policy, and support page in a single day for an app where clicking the avatar in the top-right corner did nothing — including a two-step pattern (anon client + admin API) for "verifying the current password," something Supabase has no API for
From JobRadar to Matchda — A Side Project Rebranding Story
The naming criteria and branding decisions behind renaming the feature-descriptive "JobRadar" to Matchda
Building a React Autocomplete Chip Input From Scratch — Catching the Click Before the Blur
Notes from building an autocomplete chip input without a library — the mousedown-vs-blur ordering trap and preventing uncommitted text from getting lost
The Last 20% of a Rebranding Migration — Bulk sed Replacements and the Onboarding Banner That Quietly Vanished
How I cleaned up 17 leftover screens while ripping out the Tailwind zinc palette for brand hex tokens, and the story of discovering that the onboarding entry point had disappeared entirely after switching to the new shell
Breaking Through Bot-Blocked Job Scraping With a Three-Tier Fallback (Direct Fetch → Stealth Browser → Reader Proxy + AI Extraction)
How I revived job-posting collection that had been getting nothing but 403s from Seek's Kasada bot protection, using the r.jina.ai reader proxy and Claude Haiku structured extraction — plus a debugging detour where I confused "blocked" with "expired"
Turning an AI-Generated Logo Into a Real Favicon — a Next.js Favicon Build Log
Turning an AI-generated logo image into a real Next.js favicon — from checking it at 16/32px, to hand-building favicon.ico, to color-matching
Trying Out Jina AI: Making Job Postings Readable by an LLM, and Matching Them to Resumes
From Reader turning URLs into markdown, to embeddings and rerankers — why matchda is adopting Jina AI for job matching, and hands-on usage
Turning a Design Demo Into the Real App (1) — When Two Apps Coexist
Discovering that a pretty design demo and the real logged-in app were living separate lives, and building an inventory and phase plan to replace one with the other with zero feature loss
Turning a Design Demo Into the Real App (2) — Reusing Modals and Swapping the Route
Porting per-job features by reusing existing modals via a slot pattern, and swapping the logged-in home into the MatchDa dashboard through conditional chrome (AppChrome) and component extraction
Turning a Design Demo Into the Real App (3) — Unifying the App Shell and Bulk-Mapping the Color Tone
Wrapping the remaining pages in a shared app shell to unify the chrome, then bulk-replacing zinc colors with brand tones in one perl pass — including the trap I hit along the way
When Your GitHub Grass Has Gaps, How to Fill Them With Backdated Commits (Honestly)
How to create past-dated commits with GIT_AUTHOR_DATE and GIT_COMMITTER_DATE to fill in grass gaps, and what actually counts as a contribution
Turning a Design Handoff Into a Real Product (1) — Reproducing an HTML Reference in Next.js
Reproducing a .dc.html design handoff built on a custom runtime, pixel-close, using our existing Next.js codebase's tokens, i18n, fonts, and components
Turning a Design Handoff Into a Real Product (2) — Mock Data to Real Data, and Promoting the Public Landing
Wiring the MatchDa screens that ran on mock data to real Supabase data, promoting the design demo landing into the real first screen, and adding mobile responsiveness
Turning a Design Handoff Into a Real Product (3) — Wiring CTAs and Search Into the Real Login Funnel
Wiring the landing's demo-link CTAs and search into the real login/signup funnel with Server Actions and useRouter, and handling useSearchParams with Suspense
Turning a Design Handoff Into a Real Product (4) — Optimizing a Resume Per Job Posting With Claude, and a Bug a Test Caught
Building an AI feature that analyzes an English resume against a job posting into highlights and an optimization note using Claude, applying anti-hallucination and caching, and catching a note-duplication bug through real testing
Job Sites Where Link Copying Doesn't Work? Solved With a Manual Card-Add Feature
A record of building a feature to manually enter and create a card for job postings blocked from URL scraping, using Next.js Server Actions
Building a Proper Next.js App Router Favicon: From an SVG Monogram to Shrinking a 285KB .ico Down to 2KB
The App Router icon conventions, sharp rendering, the png-to-ico size trap, and hand-rolling ICO encoding I ran into while replacing the default Next.js favicon with a brand monogram
Screen Breaks Every Evening? The prefers-color-scheme and Tailwind v4 Layer Trap
The cause of a bug where only the background turned black due to automatic OS dark mode, and the fix using color-scheme to lock it to light
For a Multilingual Site, Separate URLs Per Language Win at SEO
Why a multilingual site needs distinct per-language URLs like /en/ and /ko/ instead of a single URL that swaps content by browser language, plus hreflang and canonical basics
Renaming a Service: Custom Domain Setup and the OAuth Redirect Trap (Vercel + GoDaddy + Supabase)
A field report of rebranding from JobRadar to matchda.com — buying the domain, connecting it to Vercel, GoDaddy DNS, and Supabase Auth configuration
Knowing When to Give Up on Scraping Is a Skill Too: Landing on a Click-Through Fallback After Fighting Cloudflare + an SPA
A record of throwing a stealth browser at scraping Canva's careers page, giving up, then finding the real cause through diagnostic logs and wrapping up with a practical fallback
Drag Works, But the Order Doesn't Change — Making Sorting and Manual Order Coexist
How I fixed a bug where dnd-kit drag reordering was getting overwritten by auto-sort, then persisted the user's manual order to the database
An AI That Blocks You One More Time Before You Commit — Automating Commit Validation With a Subagent
How I built a pre-commit-validator subagent to catch hardcoded emails or missing user_id filters from slipping into commits, and the design principles behind it
It Works Locally But Not on the Server — Fighting a Job-Scraping Bot Block
How I absorbed intermittent 403s from Akamai bot blocking with retries and better headers, and fixed a bug where failures were overwriting perfectly good data
I Was Calling the Translation API Every Single Time — Caching Translations in the DB
Eliminating the waste of re-translating the same content every time a modal opens, by caching it in the DB — plus the pattern for invalidating the cache when the source text changes
Just One Username Changed — Tracking Down Hardcoded Absolute Paths
When my macOS username changed from hy to hs after switching laptops, I traced every /Users/hy absolute path across the project with grep and fixed them all — an experience and its lesson
When Claude Code Breaks Into Dotted Lines in iTerm2: CJK Width Settings and Coding Fonts
A record of fixing horizontal lines breaking into dotted dashes and Korean characters spacing out oddly in iTerm2, using the Unicode 9 width option and D2Coding/Sarasa fonts
Can You Switch iTerm2s Menus to Korean? My Actual Findings
What I learned trying to switch iTerm2 to Korean via macOS's per-app language setting, and how that differs from the real problem — garbled non-ASCII text
What You Actually Need to Save When Switching MacBooks Isn't Code — It's Keys
How to safely move signing keys, environment variables, and credentials that git clone doesn't bring along, over to a new MacBook
4 Ways to Quickly Copy Just a File Path on a MacBook
How to copy the full path of a file or folder on macOS without installing any app — Option right-click, the ⌥⌘C shortcut, terminal drag-and-drop, and pbcopy
Korean Chat Answers, Translated to English All at Once at the End — Building an Onboarding Flow
My experience collecting user info via chat right after signup, then translating and structuring it into English with a single Claude API call at completion time, saving both Korean and English
When pnpm install Dies With Exit 1: Build Script Approval and the Per-Platform Native Binary Trap
A record of fixing pnpm install exit 1 while moving an Expo monorepo configured for Replit (linux-x64) over to an Apple Silicon Mac, resolved via onlyBuiltDependencies and allowBuilds
Building a React Native (Expo) Project on a New Laptop — 4 Traps I Hit
A record of solving JDK, node, Gradle cache, and launcher issues in order while building and installing an RN app on a new Mac with copied node_modules and android folders
Moving a React Native (Expo) Project to a New Computer — Copying Without node_modules, Then Restoring the Environment
The full process of restoring an Expo project moved without node_modules using npm ci, including catching a missing nvm shell load
From 'Installing' Apps to 'Generating' Them — The Vision of an AI-Native OS
Mobile and desktop OSes are no longer just about selling apps — we're entering an era where you build what you need, together with AI, right inside the OS
Auto-Generating Slugs in the Admin Editor — DeepL + camelCase + Date
How I improved slug auto-generation from Korean titles by adding English translation, camelCase conversion, and a date suffix
Logging Into Claude Code With a Different Account, Only in a Specific Folder — Using direnv
How to combine CLAUDE_CONFIG_DIR and direnv to keep separate Claude Code login accounts per project folder
What It Means to Share a Playlist — Why I Built Sharing Into ChainPlay
Adding a share feature to ChainPlay wasn't just a convenience feature — I wanted to build a culture of sharing taste through playlists
Sharing App Content Without a Server — GitHub Pages + Android Deep Links
How I added a chain-sharing feature to ChainPlay using nothing but GitHub Pages and deep links, with no server involved
Building a Share Feature Without a Database — Shrinking a URL That Got Too Long
How I fixed a share-link URL that ballooned past 1,300 characters, by dropping titles and listing only videoIds, bringing it down to 266
Building a Tailored Resume With AI While Keeping DOCX Formatting Intact — JSZip + Claude API
How I used JSZip to manipulate a DOCX's internal XML directly, keeping the original layout untouched while letting Claude AI rewrite only the paragraph text to match a job description
Turning Off the Red Warnings in Google Search Console — Fixing Next.js i18n Redirect Errors
From 404s to redirect errors to duplicate pages — digging through Search Console errors one by one and fixing them with a few lines in next.config.ts
Managing My Application History in Code — Storing Submitted Resumes + Auto-Logging Application Dates
How I used Next.js Server Actions and Supabase to attach a submitted resume and application date directly to each job card
Got an IARC Email After Registering an App on Google Play — Just Ignore It
An IARC Live Rating Notice is just a notification that your app's age rating is now live on the store. Here's why you don't need to do anything about it
Showing an English Page to Foreign Users — By Browser Language, Not IP
How I auto-detect language in Next.js 16 proxy.ts using the Accept-Language header, with a cookie to persist the user's choice
The Menu Is Cut Off on Mobile — Fix It with a Hamburger Menu
How I fixed the scrolling issue in the Next.js blog navigation on mobile using a hamburger menu
How I Fixed Google AdSense's "Low Value Content" Rejection
When a single-feature tool site keeps getting rejected by AdSense as low-value content, here's how I restructured the pages and content to pass review
Koreans say 'better than expected' more than expected
A quiet observation about why Koreans soften every compliment with "better than I thought"
Renaming a Core App Concept — From Folder to Chain, Front to Back
What it took to rename the Folder concept to Chain across the ChainPlay app, and how a type-driven TypeScript refactor made it manageable
Why Should You Delete a Merged Feature Branch? — Local & Remote Deletion, Summarized
Why you should delete feature branches after merging, plus the commands for deleting them both locally and remotely
My Blog's Post List Vanished Because of a GitHub REST API Rate Limit
How I fixed a Next.js blog's post list disappearing after hitting the GitHub API rate limit, by switching to the GraphQL API
Upload 10 Images, Get 1 Commit — Batch Uploads With the GitHub Tree API
How I improved a Next.js admin so that selecting multiple images produces only a single commit, using the GitHub Tree API
Google Play Console - Registering for production after private testing
A summary of what you need to fill out to apply for production access after completing 14 days of private testing.
Google Play Closed Testing — the More Often You Update, the Faster Approval Comes
What I felt bumping the Tilt game version — update frequency directly affects review approval during closed testing
How to Clean Up Android Build Files — Reclaim Several GB in One Shot
A complete rundown of how to safely clean up Android build files once they start eating your disk space
Next.js Multilingual Blog SEO — Why Google Ignores /ko, and Two Fixes
How a missing x-default hreflang and unhandled isFallback posts caused a Google Search Console duplicate-page error, and how to fix both
Supabase Free Usage Restrictions
Found out the hard way that Supabase free plan only allows 2 active projects
How to Create and Use Agents
Using AI agents on the blog
[INFO] Blockchain & AI Hackathon utilizing mobile IDs
Applying for a blockchain & AI hackathon that uses mobile digital IDs
Next.js + next-intl: A /ko/ Redirect Error and a proxy.ts Conflict Ordeal
How I hit a build error while trying to fix a Google Search Console redirect error, and what I learned about the proxy.ts structure
Ollama Review (How it feels to use each model)
Review of each model - DeepSeek, EXAONE, QWEN comparison
Installing Ollama and getting started with local AI
A guide to installing Ollama and selecting a model for local AI
Why I Removed "1 min read" From the Blog Post List
Why a read-time badge backfires on a young blog, and how I removed it from Next.js components
The Day Google Crawled a Code Example on My Blog as an Actual Link
Tracing a 404 error in Search Console led to discovering Google had interpreted a filename inside a post's code example as a real URL — fixed with redirects in next.config.ts
What Happens When You Forget Canonical on a Next.js Multilingual Blog
Why Google Search Console flagged "Duplicate, Google chose different canonical than user" and how to set up canonical correctly in a next-intl environment
Why My Next.js Site Got a Scroll Animation Every Time I Navigated Pages
Tracking down two consecutive scroll-jump bugs caused by a back button implementation tangled up with scroll-behavior smooth
After GitHub Warned Me About a Huge AAB File — Moving Build Artifacts to Local Version Control
Why you shouldn't commit Android release build files (AAB/APK) to GitHub, and how to version them in a local folder instead
Adding Korean/English Support to a React Native (Expo) App — My Locale Detection Ordeal
Trying three different approaches — expo-localization, NativeModules, and the Intl API — and landing on the final answer
50 screenshots blew up my blog - debugging GitHub API limit exceedance
The story of how committing 50 images at once caused a Vercel build to spin 50 times and hit the GitHub API request limit.
Google Play Store App Registration A-Z - The whole process with screenshots
A hands-on, screenshot-filled guide to the entire Google Play Console process, from creating an app to passing a private test.
A Privacy Policy's Children's Clause and Play Store's 'Everyone' Rating Are Separate Things
My confusion over whether adding "not directed at children under 13" to a privacy policy meant I had to set a 13+ content rating
[Essay] Something Is Starting to Click
Seven weeks of building with AI — and somewhere along the way, I fell into AI engineering without meaning to
Getting an Expo app to the Play Store - From building AAB to creating store assets
A walkthrough of the build, asset creation, and bug fixing process we went through to get our React Native (Expo) game app to the Google Play Store for the first time.
One apostrophe broke my Vercel build — the YAML frontmatter trap
When local builds were fine but only Vercel failed, the culprit was a single line of YAML title with English abbreviations.
Google AdSense Rejected Me — The Reality of a Tool-Only Site
After being rejected for "low value content," I expanded content and reapplied to AdSense on a WiFi QR code generator site
I Built a WiFi QR Code Generator — My First Completed Side Project with AI
A WiFi QR code generator I made because sharing passwords to guests was annoying — React + i18n + print support
Your own playlist app without YouTube Premium - Build it yourself with React Native (Expo)
Building a YouTube playlist app from scratch with Expo SDK 54 + TypeScript — what broke and how I fixed it
How to Install Android Apps Directly - From APK to USB Debugging
How to install Android apps without Google Play and how to install them directly with ADB USB debugging.
Why GitHub Actions Commits Don't Show on Your Contribution Graph — Fix with KST Timezone
The timezone issue where GitHub Actions auto-commits don't appear on the contribution graph. One line — TZ=Asia/Seoul — fixes it.
React Native YouTube App — Android WebView Playback, Custom Button, and Keyboard Bugs
From Android WebView security policies, KeyboardAvoidingView pitfalls, and autoplay timing bugs - here are the issues and solutions we encountered while improving the YT Player app.
Launching a React Native app on the Play Store - from build to intro copywriting
A recap of our first launch, including automating AAB builds, resolving versionCode errors, writing store intro copy, and analyzing Play Console recommended actions.
Claude Code, why longer conversations get slower and how to use /clear
Claude Code gives a practical overview of why piling on context gets slower and more expensive, and how to fix it with /clear.
Why Google Ignored My Blog - 2 Next.js SEO Bug Fixes
How I discovered a missing index in Google Search Console and fixed the canonical tag and footer 404 links.
Obsidian Git Mobile Settings - Synchronizing GitHub on Android
How to clone a GitHub repo with the Obsidian Git plugin on Android and set up automatic synchronization.
The story of setting up the Obsidian Git plugin and encountering an xcrun error
How to resolve the xcrun error I encountered while connecting Obsidian to GitHub and setting up the Git plugin.
Data isolation bugs exposed by creating multi-user apps with Supabase service role
4 data isolation pitfalls and solutions when using only the service role client without RLS.
Why Is Android Background Playback So Hard — Doze, WakeLock, and Foreground Service
How I fixed a bug where track transitions stopped working when the screen turned off in a cassette music player app, using Foreground Service + PARTIAL_WAKE_LOCK
[JobRadar Part 7] Google OAuth "Database error" — Down the Supabase Trigger Rabbit Hole
Google login kept failing with "Database error saving new user" — I dug all the way to creating a new Supabase project before finding the fix was one line in a trigger function
[JobRadar Part 6] Cover Letters Done Right, UX Polish, and Adding Login
Cover letter save/download/AI review, memo and status management, direct JD input, and Supabase Auth — everything built in one day
How to run a blog with Claude Code - automate from creation to scheduled distribution
The complete workflow of running a blog with Claude Code, from post creation, translation, registration, and scheduled distribution.
[Claude Console] Buy Credits button is disabled - Causes and solutions for not checking out
In the Claude Console, the Buy button would not activate even after all payment information was entered. The cause was a bug that reset the city selection when switching languages.
JobRadar Part 5: Dropping the Automation Fantasy and Building a Practical Pipeline
After giving up on Playwright auto-scraping, I built an on-demand pipeline — URL paste → JD scraping → AI matching → cover letter generation — over two days.
JobRadar Part 4: Why I Ditched Playwright for cheerio — The Day-4 Pivot
After three days fighting Playwright, I gave up. On day 4, I completely changed direction — from auto-collection to URL-based on-demand scraping, using cheerio + JSON-LD.
How to Email Claude Support — Bypassing the AI Chatbot
When Claude support only gives you AI responses, here's the step-by-step process to create a real email ticket and reach an actual person.
Building a Claude Code Custom Agent — A Practical Guide with blog-auto-draft
How to create Claude Code custom agents to automate repetitive tasks. A step-by-step walkthrough using blog-auto-draft as a real example, from file structure to invocation.
[Claude Console] Payment Broken. DO NOT Delete Your Organization!!!
Claude Console organization deletion accidentally deleted the account — a cautionary tale
JobRadar Part 3: Deploying Playwright to Vercel Blew Up — The @sparticuz/chromium Journey
Why a scraper that ran fine locally kept exploding on Vercel. From @sparticuz/chromium adoption to ETXTBSY, 60-second timeouts, and everything in between.
Connecting Gemini to Claude Code via MCP — Using Two AIs Without Token Anxiety
A step-by-step guide to connecting Gemini as an MCP tool inside Claude Code, so you can delegate token-heavy tasks to Gemini without leaving your workflow.
[JobRadar Part 2] Supabase Schema + Playwright Scraper — Debugging Notes
JobRadar part 2. From Supabase multi-user schema design to Indeed and Seek Playwright scraper implementation. Glassdoor blocks, ETXTBSY, missing modules — all the pain points documented.
Claude Code Hooks — Automate Tasks When Claude Finishes
Auto-format on save, response completion alerts, approval request notifications — a step-by-step guide to automating repetitive tasks with Claude Code Hooks.
[JobRadar Part 1] Project Setup — I Built an AI Tool to Help Me Find a Job
From automated job scraping to AI matching — JobRadar side project part 1. A step-by-step walkthrough of the initial Next.js + Supabase + Vercel setup.
I Built an App — Now How Do I Publish It? Google Play Console from Start to Finish
A step-by-step walkthrough of publishing an app on Google Play Console for the first time — from developer account registration to AAB upload and review submission.
[App Launch] How to Gather 12 Testers — Why You Should Use Google Groups
How to efficiently recruit 12 testers for a Google Play test track. Why Google Groups beats manual email registration, and the exact order of steps that actually works.
DeepL API Integration — Adding Translation to a Next.js App
A step-by-step guide to adding translation functionality to a Next.js app using the DeepL API Free plan. From getting an API key to building a server-side route.
Scheduled Blog Post Publishing with GitHub Actions
How to set up a GitHub Actions workflow that automatically publishes blog posts on a specified date — based on a real implementation experience.
How to Register a Google Play Developer Account (2026 Guide)
A complete step-by-step guide to creating a Google Play Console developer account and completing identity verification as of 2026.
Comparing 3 translation APIs - MyMemory vs DeepL vs Claude, what should I use?
I'm comparing and contrasting my experience with MyMemory, DeepL, and Claude APIs while adding translation functionality to my blog admin.
Changing Page Title and Meta Tags per Page in React SPA — react-helmet-async
How to dynamically control title and meta tags per page in a React SPA using react-helmet-async for better SEO.
Wireless ADB Debugging — Install APKs Without a Cable
How to set up wireless ADB debugging between a MacBook and an Android device. Install APKs over Wi-Fi with a single command — no USB cable needed.
[Claude Code] How to Create and Use Skills - Your Own Slash Commands
Learn how to create and use Skills to automate repetitive tasks in Claude Code with hands-on examples.
Getting Your Site on Google — Next.js SEO Setup Guide
How to add robots.txt, sitemap.xml, Open Graph, and JSON-LD to a Next.js App Router blog to get it indexed on Google — based on a real implementation.
[App] Cassette Player App Dev Log — From Day One to the First Week
A cassette player app born out of nostalgia for tape culture — the first week bouncing between Replit and Claude Code
What is a good platform for beginners to Replit vs Claude Code?
Reviews comparing Replit and ClaudeCode.
Data inbreeding
When the data produced by AI-dependent humans stops growing, what happens to AI?
I Go to the Library to Look at Covers
Book titles reflect what an era cares about — and I think I've been going to the library just to browse them
[Claude Code] Claude Code Study Guidelines to Learn Efficiently and Quickly
Claude Code The direction to study and the basic study sequence
[AI] Stitch review
Reviews using Design AI in Stitch
[AI_StartDevelopment04] Maintain Session
If the network changes while working, the session is sometimes broken.: (
[Start AI Development_000] Opinion on AI Development (Guidelines)
Comments and Thoughts on AI Development
[AI development start_003] Create multilingual features
How to create multilingual features
[AI Start_001] Claude Code Start
start creating this blog with ai clod code
[AI Start Development_002] Add Image
Add image embedding feature
Turning 40 and Starting Over as a Developer — I Was a Legacy Developer
From developer to PM, and back to development with AI five years later — why I started this blog and how I'm teaching myself again