TRENDSHIFT #6 · 2026.06.11

KanaDojo かな道場 딥다이브
— 듀오링고를 닮은 일본어 학습 도장

KanaDojo(lingdojo/kana-dojo)는 히라가나·가타카나·한자(JLPT N5~N1)·어휘를 게임처럼 외우게 해 주는 웹 학습 플랫폼이다(kanadojo.com). 듀오링고의 "재미"와 몽키타입(Monkeytype)의 미니멀·커스터마이즈 감성을 합쳐, 100가지가 넘는 테마와 28종 일본어 폰트로 화면을 꾸미며 공부한다. 기술적으로는 Next.js 16(App Router) + React 19 + TypeScript strict 위에 Zustand 상태관리 · Feature 기반 아키텍처 · next-intl 다국어를 얹은, 실전 규모의 프론트엔드 교과서다. (저장소: lingdojo/kana-dojo · TypeScript · Vercel OSS 후원 · AGPL-3.0 · TrendShift 6위)
목차
  1. 프로젝트 한줄 요약
  2. 왜 주목받는가
  3. 기술 스택 전체 지도
  4. 아키텍처 심화 분석
  5. 디렉토리 구조 해부
  6. 학습 포인트 (기술별)
  7. 시스템 요구사항
  8. 직접 해볼 수 있는 실습 과제
  9. 관련 기술 심화 학습 로드맵
  10. 핵심 키워드 사전
  11. 참고 링크

1프로젝트 한줄 요약

이 레포가 무엇을 하는 물건인가.

핵심 메시지

"일본어 글자 암기를,
타자 연습 게임처럼 만든 학습 도장(道場)."

외국어를 배울 때 가장 지루한 구간이 '글자 외우기'다. 히라가나·가타카나 46자씩, 거기에 탁음·요음까지 수백 개를 무작정 반복해야 한다. KanaDojo는 이 반복을 '문제 풀기 게임'으로 바꾼다. 글자가 뜨면 보기에서 고르거나(객관식) 직접 로마자를 입력하고(주관식), 맞히면 콤보·연속 정답(streak)이 쌓이고 통계와 업적이 기록된다. 몽키타입에서 타자를 치듯, 듀오링고에서 레슨을 깨듯, '한 판 더'를 부르는 일본어 글자 도장이다.

KanaDojo(저장소명 lingdojo/kana-dojo, 서비스명 かな道場)는 세 개의 도장(Dojo)으로 나뉜다. Kana 도장은 히라가나·가타카나, Kanji 도장은 JLPT N5~N1 한자, Vocabulary 도장은 어휘를 다룬다. 각 도장에서 글자/단어 묶음을 고른 뒤 게임 모드를 선택하면 훈련이 시작된다. 회원가입·서버 계정이 필요 없고, 진행 상황과 설정은 모두 브라우저(localStorage)에 저장되는 100% 클라이언트 학습 도구다.

차별점은 '학습'보다 '경험'에 있다. 4가지 게임 모드(Pick·Reverse-Pick·Input·Reverse-Input)에 더해 시간제한 Blitz, 목숨이 걸린 Gauntlet, 정신없는 CrazyMode까지 있고, 100+ 테마 · 28종 일본어 폰트 · 80+ 업적으로 자기 화면을 끝없이 꾸밀 수 있다. 코드 관점에서는 "학습 콘텐츠 데이터 + 게임 엔진 + 극한의 커스터마이즈 UI"를 깔끔한 레이어로 쌓아 올린 모던 Next.js 앱이다.

용어
かな (Kana) · 가나
일본어의 표음문자. 부드러운 곡선의 히라가나(ひらがな)와 각진 가타카나(カタカナ) 두 벌이 있고, 각각 같은 소리를 적는다. 한자(漢字)와 달리 '소리'만 나타내며, 일본어 입문의 첫 관문이다. KanaDojo의 'Kana'는 바로 이 두 글자 체계를 가리킨다.
용어
JLPT (일본어능력시험) · N5~N1
Japanese-Language Proficiency Test. 일본어 비원어민의 실력을 재는 공인 시험으로 N5(입문)부터 N1(최상급)까지 5단계다. KanaDojo의 Kanji 도장은 이 등급별로 한자를 묶어, 자기 수준에 맞는 한자만 골라 연습하게 해 준다.

2왜 주목받는가

트렌딩 이유 · 경쟁 대비 장점.

일본어 학습 앱은 듀오링고·Anki·WaniKani 등 강자가 즐비하다. 그런데도 이 레포가 TrendShift 상위에 오른 이유는 세 가지다. 첫째, Vercel OSS 후원 + "good first issue" 친화라 오픈소스에 처음 기여하려는 개발자들의 유입 거점이 됐다. 둘째, 코드가 최신 스택(Next.js 16 · React 19 · Tailwind 4)의 살아있는 예제라 프론트엔드 학습 교재로 가치가 크다. 셋째, 몽키타입식 극한 커스터마이즈가 "공부 앱인데 꾸미는 재미가 있다"는 입소문을 만든다.

비교 항목일반 학습 앱KanaDojo
소스 공개대부분 비공개전체 오픈소스(AGPL-3.0) — 학습·자체 호스팅 가능
계정·서버로그인·클라우드 동기화 필수계정 불필요 · 진행상황 100% 로컬 저장
커스터마이즈제한적 테마100+ 테마 · 28 폰트 · 배경 월페이퍼
게임성고정된 레슨 흐름Pick·Input·Blitz·Gauntlet 등 다중 모드
기술 스택다양/구버전 혼재Next.js 16 + React 19 최신 표준
기존 방식의 한계
"글자 암기는 지루하고, 앱은 내 맘대로 안 된다"

가나·한자 암기는 본질적으로 단순 반복이라 금세 질린다. 시판 앱들은 학습 흐름이 고정돼 있고 화면도 바꿀 수 없어, '내 취향대로 공부하는 맛'이 없다. 게다가 진도가 회사 서버에 묶여 있어 계정·구독·프라이버시 문제가 따라붙는다.

KanaDojo의 해결
게임 루프 + 극한 커스터마이즈 + 로컬 우선

같은 반복을 콤보·정답률·업적이 쌓이는 게임 루프로 바꿔 몰입을 만든다. 100+ 테마와 일본어 폰트로 화면을 자기 것으로 꾸미게 해 '공부를 켜고 싶게' 만들고, 모든 데이터를 브라우저에 저장해 계정 없이 즉시 시작하고 프라이버시도 지킨다. 코드까지 열려 있어 마음에 안 들면 직접 고칠 수 있다.

3기술 스택 전체 지도

'일본어 학습 게임'을 떠받치는 기술들.

KanaDojo는 백엔드 서버가 거의 없는 프론트엔드 집약형 100% TypeScript 앱이다. Next.js 16 App Router로 라우팅·SSR·SEO를 처리하고, 상태는 Zustand(localStorage 영속화)로 관리한다. 일본어 텍스트 처리는 전용 라이브러리(kuroshiro·wanakana)에 맡기고, 사전 데이터는 SQLite를 브라우저에서 직접 굴린다.

레이어기술역할
프레임워크Next.js 16.2 (App Router · Turbopack)라우팅 · SSR · [locale] 다국어 라우트 · SEO/사이트맵
언어·런타임React 19 + TypeScript(strict)함수형 컴포넌트 · 엄격한 타입 · Node 20+
상태관리Zustand 5 + persist기능별 스토어 · localStorage/localforage 영속화
스타일Tailwind CSS 4 + shadcn/ui(Radix)유틸리티 CSS · 접근성 컴포넌트 · cn() 조건부 클래스
애니메이션Framer Motion 12 + canvas-confetti화면 전환·피드백 모션 · 정답 축포 효과
다국어next-intl 4네임스페이스 기반 i18n · [locale] 미들웨어 라우팅
일본어 처리kuroshiro + kuromoji · wanakana한자→읽기 변환·토큰화 · 가나↔로마자 변환
사전 데이터better-sqlite3 + sql.js(WASM)JMdict·KANJIDIC 사전을 SQLite로 · 브라우저 내 질의
차트·표Recharts 3학습 통계·진도 시각화
마크다운next-mdx-remote · react-markdown · shiki블로그·아카데미 콘텐츠 렌더 · 코드 하이라이트
난수·무작위random-js편향 없는 문제 출제(글자 무작위 선택)
분석·모니터링PostHog + Vercel Analytics/Speed Insights사용 행동 분석 · 성능 지표 · 에러 로깅
테스트Vitest 3 + Playwright + fast-check유닛(jsdom) · E2E 브라우저 · 속성 기반 테스트
컴포넌트 카탈로그Storybook 10 + a11y 애드온UI 컴포넌트 격리 개발 · 접근성 검사
품질 자동화ESLint 9 · Prettier · Husky · lint-staged커밋 훅 · 스테이징 파일 자동 검사 · 컨벤셔널 커밋
배포·인프라Vercel + Docker(멀티스테이지)kanadojo.com 호스팅 · 자체 호스팅용 standalone 이미지
용어
wanakana / kuroshiro
둘 다 일본어 텍스트를 다루는 JS 라이브러리다. wanakana는 로마자(romaji)↔가나(かな) 변환에 특화돼, 입력 모드에서 사용자가 친 ka로 바꾸거나 정답 비교에 쓴다. kuroshiro는 형태소 분석기 kuromoji를 등에 업고 한자가 섞인 문장을 읽는 법(후리가나)으로 풀어 준다. 일본어 앱의 '엔진오일' 같은 도구들.
용어
sql.js (브라우저 속 SQLite)
SQLite 데이터베이스 엔진을 WebAssembly로 컴파일해 브라우저 안에서 그대로 돌리는 라이브러리. KanaDojo는 JMdict·KANJIDIC 같은 방대한 사전을 SQLite 파일로 담아 두고, 서버 호출 없이 브라우저에서 직접 단어를 검색한다. better-sqlite3는 빌드/스크립트 단계의 Node용, sql.js는 런타임 브라우저용이다.

4아키텍처 심화 분석

시스템 구조도 · 핵심 설계 패턴.

KanaDojo의 핵심 설계는 Feature 기반(Feature-Sliced 유사) 레이어 아키텍처다. 코드를 "컴포넌트/스토어/데이터" 같은 기술 종류로 나누지 않고, "Kana/Kanji/Vocabulary/Progress" 같은 기능 단위로 자른다. 그리고 레이어를 위→아래 한 방향으로만 의존하게 강제해, 기능끼리 서로의 내부를 침범하지 못하게 한다.

비유

백화점의 층 구조를 떠올리면 된다. 1층은 입구·안내(app), 위층은 매장 묶음(widgets), 각 매장(features)은 자기 상품·창고·계산대를 스스로 갖춘다. 공용 화장실·엘리베이터는 공용시설(shared), 건물 전기·수도 같은 기반은 지하 설비(core)다. 신발 매장이 옷 매장의 창고를 함부로 뒤지지 못하듯, 기능은 다른 기능의 내부를 직접 import하지 못한다.

레이어 의존 방향 (위에서 아래로만)

┌───────────────────────────────────────────────┐ │ app/ Next.js 라우트·레이아웃·페이지 │ ← URL과 화면 연결 └───────────────────────────────────────────────┘ │ (조립만) ▼ ┌───────────────────────────────────────────────┐ │ widgets/ 여러 기능을 한 화면으로 조립 │ ← TrainingGame, 메뉴 └───────────────────────────────────────────────┘ │ ▼ ┌───────────────────────────────────────────────┐ │ features/ 자기완결 기능 모듈 │ ← Kana, Kanji, Progress… │ (components · store · data · lib · facade) │ 비즈니스 로직의 집 └───────────────────────────────────────────────┘ │ ▼ ┌───────────────────────────────────────────────┐ │ entities/ 도메인 모델·셀렉터·순수 헬퍼 │ ← kana / kanji / vocabulary └───────────────────────────────────────────────┘ │ ▼ ┌───────────────────────────────────────────────┐ │ shared/ 공용 UI·훅·유틸·스토어 │ ← 버튼, cn(), 세션 기록… └───────────────────────────────────────────────┘ │ ▼ ┌───────────────────────────────────────────────┐ │ core/ 인프라: i18n · 분석 · 기본 설정 │ ← next-intl, PostHog └───────────────────────────────────────────────┘ 규칙: 위 레이어는 아래를 쓸 수 있지만, 아래가 위를 알면 안 된다. 기능끼리(features ↔ features)는 서로의 '내부'를 직접 import 금지. 반드시 공개 입구(facade / index.ts)를 통해서만 연결.

설계 패턴 ① — Facade(공개 입구) 패턴

각 기능 폴더에는 facade/ 또는 index.ts라는 '정문'이 있다. 바깥에서는 이 정문이 내보낸 것만 쓸 수 있고, 폴더 안쪽의 컴포넌트·스토어 파일을 직접 가져다 쓰면 안 된다. 예를 들어 Kana 기능은 features/Kana/facade/에서 useKanaContent·useKanaSelection만 공개하고, 내부의 useKanaStore나 게임 컴포넌트는 숨긴다. 덕분에 내부 구현을 바꿔도 바깥 코드가 깨지지 않는다.

// entities/kana/index.ts — 도메인의 공개 입구(정문)
export { kana } from '@/features/Kana/data/kana';
export type { KanaGroup } from '@/features/Kana/data/kana';
export { flattenKanaGroups } from '@/features/Kana/lib/flattenKanaGroup';
export { getSelectionLabels } from './selection';
// 바깥(widgets·app)은 이 파일만 import → 내부 파일 경로는 자유롭게 변경 가능

설계 패턴 ② — Zustand 스토어를 '기능별'로 쪼개기

전역 상태를 거대한 하나의 store에 몰지 않고, 기능마다 작은 store를 둔다. useKanaStore(선택한 글자 묶음·게임 모드), useStatsStore(통계·업적), usePreferencesStore·useCustomThemeStore(테마·폰트·월페이퍼)처럼 책임이 분리돼 있다. 그리고 통계·설정처럼 오래 남겨야 하는 상태는 persist 미들웨어로 localStorage에 자동 저장한다.

// features/Progress/store/useStatsStore.ts (요지)
import { create } from 'zustand';
import { persist, createJSONStorage } from 'zustand/middleware';

const useStatsStore = create(
  persist(
    (set) => ({
      allTime: { totalCorrect: 0, bestStreak: 0 /* … */ },
      recordAnswer: (ok) => set(/* 정답/오답 집계 */),
    }),
    { name: 'stats', storage: createJSONStorage(() => localStorage) } // ← 브라우저에 영속
  )
);
비유

거대한 store 하나는 '모든 물건을 한 서랍에 몰아넣은 책상'과 같아서, 뭐 하나 꺼내려면 전부 들썩인다. 기능별 store는 '용도별로 라벨 붙인 여러 서랍'이다. Kana 서랍을 열어도 Stats 서랍은 그대로다. persist는 그 서랍을 퇴근할 때 자동으로 잠가 두는 자물쇠라, 다음 날(새 방문) 열면 어제 그대로다.

설계 패턴 ③ — 학습 콘텐츠 = 순수 데이터, 출제 = 순수 함수

가나·한자·어휘는 features/*/data/순수 데이터(JSON/TS 배열)로 담겨 있고, "다음 문제를 무엇으로 낼까"는 lib/순수 함수가 결정한다. 부작용(화면 그리기·저장)과 계산(출제·정답 판정)을 분리했기 때문에, 출제 로직만 떼어 내 단위 테스트할 수 있다(실제로 generateKanaQuestions·isKanaInputAnswerCorrect 테스트가 있다).

// features/Kana/lib/generateKanaQuestions.ts — 편향 없는 무작위 출제
import { Random } from 'random-js';
const random = new Random();

export function generateKanaQuestion(selected: KanaCharacter[]): KanaCharacter {
  if (selected.length === 0) throw new Error('No kana selected');
  const i = random.integer(0, selected.length - 1); // random-js: 균일 분포
  return selected[i];
}

5디렉토리 구조 해부

주요 폴더·파일의 역할.

kana-dojo/ ├── app/ Next.js App Router (화면·라우팅만) │ └── [locale]/ 다국어 라우트: /en, /es … │ ├── kana/ 가나 도장 페이지 (train/ · train/timed/ 서브라우트) │ ├── kanji/ 한자 도장 │ ├── vocabulary/ 어휘 도장 │ └── (main)/ 라우트 그룹 (공용 레이아웃) │ ├── progress/ 진도·통계 (업적은 progress 내 통합) │ └── preferences/ 테마·폰트 설정 ├── widgets/ 여러 기능을 한 화면으로 조립 │ ├── TrainingGame/ 훈련 화면 오케스트레이터(핵심) │ └── menu/ Kana/Kanji/Vocab 메뉴 ├── features/ ★ 자기완결 기능 모듈 (로직의 집) │ ├── Kana/ components·store·data·lib·facade │ ├── Kanji/ services 포함(사전 캐시) │ ├── Vocabulary/ │ ├── Progress/ 통계 집계·차트 │ ├── Achievements/ 업적 규칙·해금 │ ├── Preferences/ 테마/폰트 데이터·스토어 │ ├── Conjugator/ 동사 활용 연습 │ ├── Translator/ 번역 도구 │ ├── AnkiConverter/ Anki 덱 변환기 │ └── …(Blog·Academy·CrazyMode 등 20+) ├── entities/ 도메인 모델 (kana·kanji·vocabulary) ├── shared/ 공용 UI·훅·유틸·스토어·events·infra ├── core/ 인프라: i18n(locales) · analytics ├── data/ 빌드용 원천 데이터·월페이퍼 소스 ├── scripts/ i18n 검증·상수 생성·SEO·사운드 등 자동화 ├── docs/ ARCHITECTURE·UI_DESIGN·기여 가이드 ├── public/ 정적 자산(폰트·이미지·사전 파일) ├── Dockerfile 멀티스테이지 프로덕션 이미지(standalone) ├── proxy.ts next-intl 미들웨어(로케일 라우팅) ├── next.config.ts 보안 헤더(CSP·X-Frame) · 이미지 설정 └── package.json 스크립트·의존성

주목할 점 몇 가지. app/[locale]/의 대괄호는 Next.js의 동적 라우트로, URL의 언어 코드(en·es)를 변수처럼 받는다. train/ 페이지에서 게임 모드(Pick·Input 등)는 URL 세그먼트가 아닌 클라이언트 상태로 처리하고, 시간제한 모드는 train/timed/ 서브라우트를 별도로 사용한다. proxy.ts는 예전 Next.js의 middleware.ts에 해당하는 파일(최신 명명 규약)로, 들어오는 요청의 언어를 감지해 알맞은 로케일 경로로 보내는 관문 역할을 한다.

또 하나, scripts/가 유난히 풍부하다. 번역 키 누락 검사(i18n:validate), 타입 자동 생성, Anki 변환, 월페이퍼 이미지 처리, SEO 헬스체크, 번들 크기 점검까지 — "손으로 반복할 일은 전부 스크립트로"라는 성숙한 OSS 운영 문화를 보여 준다.

6학습 포인트 (기술별)

이 레포에서 무엇을, 어떻게 배울 수 있나.

학습 포인트 ① — Next.js 16 App Router + 다국어

URL에 언어를 싣는 i18n 라우팅

app/[locale]/ + next-intl + proxy.ts 조합으로 다국어를 구현했다. core/i18n/routing.tslocalePrefix: 'never'가 설정돼 있어 URL에 /en/·/ko/ 접두사가 붙지 않는다 — 로케일은 쿠키·Accept-Language 헤더로 감지·저장되고, 사용자 URL은 /kana/ 형태 그대로다. app/[locale]/은 Next.js 내부 라우팅 구조용이며 URL에는 직접 노출되지 않는다. 페이지는 locale을 받아 알맞은 번역을 렌더한다.

실습 아이디어: 한국어 로케일(ko)을 추가해 보라. core/i18n/routing.tslocales 배열에 'ko'를 넣고 locales/ko.json을 만든 뒤 npm run i18n:check로 누락 키를 잡아내는 흐름을 경험할 수 있다.

학습 포인트 ② — Zustand 상태관리 + 영속화

"가볍게 전역, 알아서 저장"

Redux의 보일러플레이트 없이 create() 한 번으로 store를 만들고, persist 미들웨어로 새로고침에도 살아남는 상태를 구현하는 법을 배운다. 기능별로 store를 쪼개 책임을 분리하는 실전 패턴이 그대로 들어 있다.

실습 아이디어: useKanaStore를 읽고, "마지막으로 고른 게임 모드"를 persist로 저장하도록 바꿔, 재방문 시 직전 모드가 복원되게 만들어 보라.

학습 포인트 ③ — 게임 루프와 순수 함수 설계

'문제 출제·정답 판정'을 테스트 가능한 함수로

출제(generateKanaQuestion)와 채점(isKanaInputAnswerCorrect)을 화면과 분리된 순수 함수로 두면, 가짜 입력을 넣어 결과만 검증하는 단위 테스트가 가능하다. random-js로 균일 분포 난수를 쓰고, fast-check로 속성 기반 테스트까지 거는 모범 사례를 볼 수 있다.

실습 아이디어: wanakana로 "사용자가 친 로마자"와 "정답 가나"를 비교하는 채점 함수를 작성하고, ka/ka-·대소문자 등 엣지 케이스 테스트를 추가해 보라.

학습 포인트 ④ — 브라우저 속 데이터베이스(sql.js/WASM)

서버 없이 사전을 검색하는 법

방대한 일본어 사전을 SQLite 파일로 담아 sql.js(WebAssembly)로 브라우저에서 질의하는 구조는, "백엔드 없이도 무거운 데이터를 다루는" 정적 웹앱 설계의 핵심 기법이다. 빌드 시엔 better-sqlite3(Node), 런타임엔 sql.js(브라우저)로 역할을 나눈 점도 배울 만하다.

실습 아이디어: 작은 단어 테이블을 SQLite로 만들어 sql.js로 로드하고, 입력어로 LIKE 검색해 결과를 화면에 띄우는 미니 사전을 구현해 보라.

학습 포인트 ⑤ — 성숙한 OSS 운영(품질 자동화)

Husky · lint-staged · Storybook · 컨벤셔널 커밋

커밋 직전 자동 검사(Husky+lint-staged), 컴포넌트 격리 개발(Storybook+a11y), Vitest+Playwright 다층 테스트, 번들 크기 모니터링까지 — 혼자 만든 토이가 아니라 '여러 명이 기여하는 제품'을 운영하는 표준 셋업을 통째로 학습할 수 있다.

실습 아이디어: "good first issue" 라벨이 붙은 이슈를 하나 골라, CONTRIBUTING 가이드대로 포크→수정→npm run check→PR까지 오픈소스 기여 전 과정을 밟아 보라.

7시스템 요구사항

직접 돌려 보려면 무엇이 필요한가.

항목요구사항비고
Node.js20 이상Dockerfile 기준 node:20-alpine
패키지 매니저npm (package-lock.json 제공)npm ci로 재현 가능 설치
OSWindows / macOS / Linux / WSLCLAUDE.md에 셸별 명령 구분 안내
실행(개발)npm install && npm run devTurbopack 개발 서버 · localhost:3000
검증npm run checktsc + ESLint (빌드는 검증용으로 쓰지 말라고 명시)
Dockerdocker compose up (dev)프로덕션은 멀티스테이지 Dockerfile
브라우저(이용자)최신 크롬·사파리·파폭WASM(sql.js)·localStorage 지원 필요

이용자 입장에선 설치가 전혀 필요 없다. kanadojo.com에 접속만 하면 되고, 모든 진행상황은 브라우저에 저장되므로 계정도 필요 없다. 개발자로서 코드를 돌려 보려면 Node 20과 위 명령이면 충분하다.

8직접 해볼 수 있는 실습 과제

난이도별로 손을 움직여 보자.

🟢 입문 ★☆☆☆☆ · 환경 적응

① 로컬 실행 + 테마 하나 추가. 레포를 클론해 npm run dev로 띄운 뒤, features/Preferences/data/themes/themeDefinitions.ts에 내 색조합 테마를 하나 추가하고 화면에서 선택해 본다. "데이터를 바꾸면 UI가 바뀐다"는 데이터 주도 설계를 체감하는 과제.

🟢 초급 ★★☆☆☆ · 데이터 읽기

② 가나 데이터 구조 분석. features/Kana/data/kana.tslib/flattenKanaGroup.ts를 읽고, '그룹(행) → 개별 글자'로 펼치는 흐름을 그림으로 정리한다. 그런 다음 탁음·요음 한 그룹이 빠졌다고 가정하고 데이터에 추가해 본다.

🟡 중급 ★★★☆☆ · 로직 + 테스트

③ 채점 함수에 테스트 추가. features/Kana/lib/isKanaInputAnswerCorrect.ts를 읽고, 장음()·n받침()·대소문자 같은 엣지 케이스에 대한 Vitest 케이스를 직접 작성한다. npm run test:watch로 빨강→초록을 만든다.

🟡 중상급 ★★★★☆ · 기능 확장

④ 새 게임 모드 한 판 만들기. 기존 Pick/Input을 참고해 "음성 듣고 고르기" 같은 새 모드의 뼈대를 features/Kana/components/Game/에 추가하고, train/ 페이지의 클라이언트 상태와 연결한다. Facade·store 규칙을 지키며 기능을 끼워 넣는 연습.

🔴 고급 ★★★★★ · 인프라/아키텍처

⑤ 한국어 로케일 풀스택 적용. routing.tsko 추가 → locales/ko.json 작성 → i18n:check로 누락 키 0 만들기 → 미들웨어 동작 확인 → 메타데이터/사이트맵까지 한국어가 반영되는지 점검한다. 다국어 시스템 전체를 관통하는 종합 과제.

9관련 기술 심화 학습 로드맵

4주에 걸쳐 이 레포를 '내 것'으로.

주차주제학습 내용 · 산출물
1주차Next.js App Router 기초서버/클라이언트 컴포넌트, 동적 라우트([locale])·정적 서브라우트(train/timed/), 레이아웃·로딩. → 미니 라우팅 앱 1개
2주차Zustand + 영속화create·셀렉터·persist·기능별 store 분리. → 카운터를 새로고침에도 유지되게 만들기
3주차게임 로직 + 테스트순수 함수 출제/채점, random-js·wanakana, Vitest·fast-check. → 가나 퀴즈 핵심 로직 + 테스트 셋
4주차아키텍처 + OSS 운영Feature 레이어·Facade, Storybook, Husky/lint-staged, Docker. → 본 레포에 PR 1건 오픈
학습 팁

처음부터 코드 전체를 이해하려 하지 말 것. "한 글자 문제가 화면에 뜨고 → 내가 답하고 → 통계가 1 늘어나는" 한 줄기 흐름을 골라, 그 흐름이 지나는 파일만(page → widget → feature → store) 순서대로 따라가는 게 가장 빠르다. 나머지 기능은 같은 패턴의 반복이다.

10핵심 키워드 사전

한 줄로 빠르게 짚는 용어.

용어의미
Kana(가나)일본어 표음문자. 히라가나·가타카나 두 벌.
JLPT N5~N1일본어능력시험 등급. N5 입문 ~ N1 최상급.
App RouterNext.js의 폴더=라우트 방식. 서버 컴포넌트 기본.
동적 라우트 [x]URL 일부를 변수로 받는 폴더. 예: [locale]. 게임 모드는 동적 라우트가 아닌 클라이언트 상태로 처리.
Zustand훅 기반 경량 전역 상태관리 라이브러리.
persiststore를 localStorage에 자동 저장하는 미들웨어.
next-intl네임스페이스 기반 Next.js 다국어 라이브러리.
Facade기능 폴더의 '정문'. 공개 API만 내보내 내부를 숨김.
Feature 기반 구조코드를 기술 종류가 아닌 기능 단위로 자르는 아키텍처.
wanakana로마자↔가나 변환 라이브러리. 입력·채점에 사용.
kuroshiro / kuromoji일본어 형태소 분석·읽기 변환(후리가나) 도구.
sql.jsWASM으로 브라우저에서 도는 SQLite. 사전 검색에 사용.
shadcn/uiRadix 기반 복붙형 React 컴포넌트 모음.
StorybookUI 컴포넌트를 화면과 분리해 개발·문서화하는 도구.
Husky / lint-stagedgit 커밋 훅으로 스테이징 파일을 자동 검사.
TurbopackNext.js의 차세대 번들러. 빠른 개발 서버.
AGPL-3.0네트워크 사용 시에도 소스 공개를 요구하는 강한 카피레프트 라이선스.

11참고 링크