코드와 일상을
기록하는 공간

프론트엔드 개발자 세호입니다. 매일 조금씩 배우고, 가끔 삽질하고, 그 과정을 솔직하게 남깁니다.

147

작성한 글

63

코드 스니펫

24.8K

총 조회수

2년+

운영 기간

실전 기술 가이드

실무에서 겪은 시행착오와 해결법을 정리했습니다

프론트엔드

Next.js 15 서버 컴포넌트 분리 전략

App Router가 안정화되면서 서버 컴포넌트 활용법도 많이 바뀌었다. 핵심은 단순하다. 데이터 패칭은 서버 컴포넌트에, 인터랙션은 클라이언트 컴포넌트에. 가장 흔한 실수는 서버 컴포넌트 안에서 useState를 호출하는 것이다. 인터랙티브 요소를 별도 파일로 추출하고 "use client"를 상단에 선언하면 된다. Server-to-Client Composition 패턴을 쓰면 클라이언트 번들 크기를 줄이면서도 인터랙션을 유지할 수 있다.

백엔드

Supabase Edge Functions 실전 가이드

Deno 런타임 위에서 돌아가는 Edge Functions는 생각보다 쓸만하다. Cold start가 거의 없고, TypeScript를 네이티브로 지원하며, Supabase 클라이언트를 바로 임포트해서 DB 쿼리를 날릴 수 있다. 주의할 점은 npm 패키지 호환성이다. Node.js 전용 패키지는 안 돌아가는 경우가 많으니, Deno 호환 여부를 미리 확인해야 한다. 배포는 supabase functions deploy 한 줄이면 끝난다.

개발 일지

TypeScript 5.7의 달라진 타입 추론

타입 추론이 한층 더 똑똑해졌다. satisfies 연산자 개선, 데코레이터 메타데이터 지원, 새로운 유틸리티 타입이 추가되었다. 특히 NoInfer 유틸리티 타입은 제네릭 함수에서 의도치 않은 타입 확장을 방지해준다. 실무에서 가장 체감되는 변화는 조건부 타입의 추론 정확도가 올라간 것이다. 이전에는 as 캐스팅으로 우회하던 패턴들을 이제 자연스럽게 작성할 수 있다.

개발 팁 모음

짧지만 유용한 노하우

Tailwind CSS v4 마이그레이션 체크리스트

@tailwind 지시어가 @import로 변경됐다. JIT 모드가 기본이 되면서 purge 설정이 불필요해졌고, 색상 시스템이 oklch 기반으로 바뀌었다. 가장 많이 깨지는 부분은 커스텀 색상 정의와 plugin 호환성이다.

Docker Compose 로컬 환경 통일 팁

depends_on + healthcheck 조합으로 서비스 시작 순서를 보장하자. volumes로 데이터 영속성을 확보하고, env_file로 비밀값을 분리하면 "제 컴퓨터에서는 되는데요"를 끝낼 수 있다.

React Query vs SWR (2026 기준)

React Query는 devtools, mutation 관리, 오프라인 지원이 강점. SWR은 가볍고 심플하다. 대규모 앱이면 React Query, 간단한 프로젝트면 SWR. 최근 React Query v6에서 suspense 지원이 안정화되면서 격차가 벌어지는 추세다.

Git 워크플로우: trunk-based 3개월 후기

GitFlow에서 trunk-based로 바꾸고 느낀 점: 배포 주기가 빨라지고, 충돌이 줄었다. 대신 feature flag와 CI 파이프라인이 튼튼해야 한다. 팀 규모가 5명 이하면 적극 추천한다.

인기 코드 스니펫

실무에서 바로 쓸 수 있는 코드 조각

TypeScriptuseDebounce 커스텀 훅
342회 조회
function useDebounce<T>(value: T, delay: number): T {
  const [debounced, setDebounced] = useState(value);
  useEffect(() => {
    const timer = setTimeout(() => setDebounced(value), delay);
    return () => clearTimeout(timer);
  }, [value, delay]);
  return debounced;
}
TypeScriptPrisma soft delete 미들웨어
289회 조회
prisma.$use(async (params, next) => {
  if (params.action === 'delete') {
    params.action = 'update';
    params.args.data = { deletedAt: new Date() };
  }
  return next(params);
});
TypeScriptNext.js 미들웨어 인증 패턴
517회 조회
export function middleware(req: NextRequest) {
  const token = req.cookies.get('session')?.value;
  if (!token && req.nextUrl.pathname.startsWith('/dashboard')) {
    return NextResponse.redirect(new URL('/login', req.url));
  }
  return NextResponse.next();
}

자주 묻는 질문

이 블로그에 대해 궁금한 점들

어떤 기술 스택을 주로 사용하나요?+

Next.js + TypeScript + Tailwind CSS를 메인으로 쓰고 있습니다. 백엔드는 Supabase와 Prisma를 주로 활용하고, 배포는 Vercel을 사용합니다. 최근에는 Deno와 Bun도 실험적으로 써보고 있습니다.

글은 어떤 주기로 올리나요?+

주 1~2회 정도를 목표로 하고 있습니다. 개발 일지는 무언가 삽질하거나 배운 게 있을 때, 기술 글은 충분히 정리가 됐을 때 올립니다. 스니펫은 실무에서 유용했던 코드를 수시로 기록합니다.

글 주제는 어떻게 정하나요?+

대부분 실무에서 직접 겪은 문제와 해결 과정을 글로 옮깁니다. "이거 나도 삽질했는데 누가 정리해줬으면 좋겠다" 싶은 것들이 좋은 글감이 됩니다.