
Electron + React + TypeScript로 10일 만에 완성한 교사용 올인원 데스크탑 위젯 개발기
만들게 된 계기
아내는 중학교 교사다. 어느 날 아내가 보여준 인스타그램 릴스 하나가 시작이었다.
영상 속 바탕화면에는 시간표, 급식, 학사일정, 할 일 목록이 한눈에 정리되어 있었다. 아내가 "나도 이런 거 쓰고 싶다"고 했고, 개발자인 내가 직접 만들어보기로 했다.
교사들은 매일 아침 이런 것들을 확인한다:
- 오늘 몇 교시에 어떤 반 수업이지?
- 급식 메뉴가 뭐지?
- 이번 주 학교 행사가 뭐 있지?
- 미세먼지 괜찮나?
이걸 매번 나이스, 컴시간, 날씨 앱을 따로 열어서 확인하고 있었다. 한 화면에 다 보이면 좋겠다는 단순한 생각이 프로젝트의 시작이었다.
기술 스택을 고른 이유
| 기술 | 선택 이유 |
|---|---|
| Electron | Windows 바탕화면 위에 상주하는 앱이 필요했다. 웹 기술로 네이티브 앱을 만들 수 있는 건 Electron뿐 |
| React + TypeScript | 익숙한 스택. 위젯 단위 컴포넌트 구조가 딱 맞았다 |
| Zustand | Redux는 과하고, 위젯별 독립 상태 관리에 가볍고 좋았다 |
| Tailwind CSS v4 | 레이아웃은 Tailwind, 디자인 디테일은 inline style로 분리 |
| electron-vite | CRA 대신 Vite 기반으로 빠른 HMR과 빌드 |
주요 기능
한눈에 보는 교사의 하루
┌───────┬────────────────────────┐
│ │ [시계] [날씨+미세먼지] [현재수업] [퇴근+명언] │
│ 바탕화면 ├──────┬───────┬─────────┤
│ 빠른폴더 │ 시간표 │ 할일+D-Day │ 스마트도구+급식 │
│ (파일정리) │ │ +메모 │ +학사일정 │
└───────┴──────┴───────┴─────────┘
12개 위젯을 하나의 화면에 담았다:
- 시계 + 날씨 + 미세먼지: wttr.in + 에어코리아 API 실시간 연동
- 시간표: 컴시간 자동 불러오기 + 수동 입력 (초등/중등/특수반 대응)
- 현재 수업: 지금 몇 교시인지, 남은 시간은 얼마인지
- 급식: 나이스 API로 오늘의 중식 자동 표시
- 학사일정: 이번 달 학교 행사 목록
- 할 일 / D-Day / 메모: 교사 업무 관리 필수 3종
- 스마트 도구: 타이머, 랜덤 학생 뽑기, 미제출자 관리, 전화번호부, 공문 문서번호
- 바탕화면 파티션: 파일/폴더를 드래그앤드롭으로 정리하는 사이드바
삽질 기록
1. 컴시간 파서가 Electron에서 안 돌아간다
comcigan-parser npm 패키지를 설치했는데 File is not defined 에러가 터졌다. 원인은 패키지 내부에서 쓰는 undici가 Electron의 Node.js 환경과 호환이 안 되는 것이었다.
해결: npm 패키지를 버리고 Node.js http 모듈 + iconv-lite로 컴시간 API를 직접 구현했다. 컴시간 웹사이트의 JavaScript를 분석해서 데이터 파싱 로직을 그대로 옮겼다. 결과적으로 외부 의존성도 줄이고, 원하는 대로 커스터마이징할 수 있게 됐다.
2. Tailwind v4의 함정
Tailwind CSS v4에서 text-red-500 같은 유틸리티 클래스가 먹히질 않았다. v4부터는 설정 방식이 완전히 바뀌어서 기존 방식으로는 커스텀 클래스가 동작하지 않았다.
해결: 레이아웃(flex, grid, gap)만 Tailwind로, 색상/그림자/radius 같은 디자인은 전부 style={{}}로 분리했다. 오히려 Tailwind에 대한 의존도를 낮추니 코드가 직관적이 됐다.
3. 바탕화면에 고정하기
Rainmeter처럼 위젯을 바탕화면 레벨에 고정하고 싶었다. Electron에는 alwaysOnBottom 같은 API가 없다.
해결: koffi 패키지로 Windows API를 직접 호출했다.
// Windows user32.dll의 SetWindowPos를 직접 호출
const user32 = koffi.load('user32.dll')
SetWindowPos(hwnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE)
1초마다 창의 Z-order를 맨 뒤로 보내되, 위젯을 클릭해서 조작할 때는 건드리지 않는 로직을 추가했다. 다른 창을 열면 위젯은 뒤에 숨고, 다 닫으면 바탕화면처럼 보인다.
4. 동명 학교 검색 문제
같은 이름의 학교가 여러 지역에 존재한다. 처음에는 학교 이름 기준으로 매칭했더니 하나가 덮어씌워졌다.
해결: 학교 코드(schoolCode) 기준으로 매칭하고, 드롭다운에 지역 + 주소를 함께 표시해서 사용자가 구분할 수 있게 했다.
배포
GitHub Releases로 배포했다. electron-builder로 두 가지 형태를 만든다:
- Setup.exe — 일반 설치 파일 (바탕화면 바로가기 생성)
- Portable.exe — 설치 없이 바로 실행 (USB에 넣고 다닐 수 있음)
electron-updater를 연동해서 앱 실행 시 자동으로 새 버전을 확인한다. 새 버전이 나오면 알림이 뜨고, 클릭하면 업데이트된다.
배포 과정:
# 1. 버전 올리기 (package.json)
# 2. 빌드
npm run build:win
# 3. GitHub에 릴리즈 생성
gh release create v0.1.0 dist/*.exe --title "v0.1.0"
숫자로 보는 개발 과정
| 항목 | 수치 |
|---|---|
| 개발 기간 | 10일 (2026.03.19 ~ 03.29) |
| 총 커밋 수 | 47개 |
| 완료 Phase | 12개 |
| 위젯 수 | 12종 |
| 외부 API | 4개 (wttr.in, 에어코리아, NEIS, 컴시간) |
| 의존성 패키지 | 14개 |
느낀 점
"쓰는 사람이 옆에 있으니 빠르다."
사용자가 바로 옆에서 "이거 불편해", "여기 글씨가 작아", "이 기능 필요해"라고 말해주니까 기획-개발-피드백 사이클이 실시간으로 돌았다. PM도 디자이너도 필요 없었다. 사용자 한 명의 구체적인 니즈가 가장 좋은 기획서였다.
Electron은 생각보다 강력하다.
Windows API 직접 호출(바탕화면 고정), 파일 시스템 접근(바탕화면 파티션), 시스템 트레이, 알림까지 — 웹 기술만으로 네이티브 수준의 데스크탑 앱을 만들 수 있다는 게 새삼 놀라웠다.
Claude Code와 함께 개발하면 속도가 다르다.
이 프로젝트는 Claude Code와 페어 프로그래밍으로 진행했다. API 연동, 레이아웃 설계, 버그 수정, 배포 설정까지 대화하면서 같이 만들었다. 혼자였으면 10일이 아니라 한 달은 걸렸을 것이다.
앞으로
아내가 실제로 학교에서 쓰기 시작하면 피드백이 쏟아질 것이다. 그때 다시 업데이트할 예정이다. 혹시 교사이시거나 주변에 교사가 계시다면, 한번 써보시고 피드백 주시면 감사하겠습니다.
GitHub: https://github.com/hgko1207/teacher-desktop-widget
다운로드: GitHub Releases
IT 기술과 개발 내용을 포스팅하는 블로그
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!