글자 수 세기, AI로 10분 만에 직접 만들어 쓰기
글자 수, 단어 수, 원고지 매수를 실시간으로 계산하는 도구를 직접 만들었습니다. 외부 API 없이 순수 JavaScript로 완성한 과정을 공유합니다.
2026년 5월 27일5분 읽기2 조회
?
#글자수#원고지#AI코딩#바이브코딩#뚝딱공방#글쓰기
✦ 라이브 데모AI 프롬프트로 생성한 결과물
위 화면은 이 포스트의 프롬프트를 AI에 입력해서 생성한 샘플입니다
AI 프롬프트 공개
## 실제 사용한 프롬프트
---
### 1단계 — 기본 구조 요청
```
Next.js 14 + TypeScript + Tailwind로 글자 수 세기 컴포넌트를 만들어줘.
요구사항:
- 'use client' 컴포넌트
- 큰 textarea (최소 200px 높이)
- 실시간 카운트 (onChange마다):
- 전체 글자 수
- 공백 제외 글자 수
- 단어 수 (공백 기준)
- 문장 수 (. ! ? 기준)
- 문단 수 (빈 줄 기준)
- 읽기 예상 시간 (분당 300자)
- 200자 원고지 매수
- 400자 원고지 매수
- useMemo로 최적화
- 다크모드 대응 (CSS 변수 사용)
```
---
### 2단계 — UI 카드 그리드
```
글자 수 세기 결과를 카드 그리드로 표시해줘:
- 각 카드: 이모지 아이콘 + 숫자(크게) + 레이블
- 상단 4개 카드(글자 수 관련): 2열 그리드 → sm: 4열
- 하단 4개 카드(기타): 동일
- 전체 글자 수와 공백 제외 수는 brand-500 색상으로 강조
- 카드 배경은 var(--bg-2) 사용
```
---
### 3단계 — 붙여넣기/초기화 기능
```
글자 수 세기에 다음을 추가해줘:
1. textarea 상단 툴바에 붙여넣기 버튼 (navigator.clipboard.readText)
2. 초기화 버튼 (텍스트 비우기)
3. textarea 우측 상단에 현재 글자 수 표시
```
---
💡 **팁**: 정규식 패턴은 AI에게 설명으로 요청하면 직접 작성하는 것보다 더 정확합니다. "빈 줄로 구분된 문단 감지"처럼 자연어로 설명하세요.
왜 글자 수 세기 도구를 직접 만들었나?
블로그 포스트를 쓰거나, 공모전 원고를 제출할 때 글자 수 제한이 있습니다. 검색하면 글자 수 세기 사이트가 많지만, 광고가 많고 모바일에서 불편합니다.
특히 원고지 매수 계산은 구글 검색으로 바로 나오지 않습니다. 자주 쓰는 도구니까 직접 만들어 블로그에 붙여두기로 했습니다.
라이브 데모
위의 글자 수 세기 도구를 직접 사용해보세요.
- 텍스트를 입력하거나 붙여넣기 버튼으로 클립보드 내용을 가져옵니다
- 아래 8개 카드가 실시간으로 업데이트됩니다
- 전체 글자 수 / 공백 제외 글자 수
- 단어 수 / 문장 수 / 문단 수
- 읽기 예상 시간 / 200자 원고지 / 400자 원고지
- 초기화 버튼으로 텍스트를 지웁니다
코드 핵심 포인트
1. 실시간 계산 — useMemo 활용
텍스트가 바뀔 때마다 8개 통계를 다시 계산합니다. useMemo로 불필요한 재계산을 방지합니다.
const stats = useMemo(() => calcStats(text), [text])
2. 각 통계 계산 로직
const total = text.length
const noSpace = text.replace(/\s/g, '').length
const words = text.trim().split(/\s+/).length
const sentences = (text.match(/[.!?]+/g) ?? []).length
const paragraphs = text.split(/\n\s*\n/).filter(p => p.trim().length > 0).length
// 분당 300자 기준 읽기 시간
const readingMin = parseFloat((noSpace / 300).toFixed(1))
// 원고지 (공백 제외 기준)
const page200 = parseFloat((noSpace / 200).toFixed(1))
const page400 = parseFloat((noSpace / 400).toFixed(1))
3. 클립보드 붙여넣기
const handlePaste = async () => {
const clipText = await navigator.clipboard.readText()
setText(clipText)
}
navigator.clipboard API는 HTTPS 환경에서만 동작합니다. 로컬 개발 시 localhost는 예외적으로 허용됩니다.
마무리
이 도구는 외부 API가 없어서 가장 빠르게 완성했습니다. 순수 JavaScript 로직만으로 모든 통계를 계산합니다.
바이브코딩의 진가는 이런 **"외부 의존성 없는 도구"**에서 더 잘 발휘됩니다. AI가 정규식과 통계 계산 로직을 즉시 완성해줬습니다.
시리즈 마무리
AI 뚝딱 공방 시리즈 6편이 모두 완성됐습니다. 단위 변환기, 번역기, 환율 계산기, 뽀모도로 타이머, 색상 코드 변환기, 글자 수 세기 — 모두 AI와 함께 10분 안에 만든 도구들입니다.
소스 코드
'use client'
import { useState, useMemo } from 'react'
function calcStats(text) {
const total = text.length
const noSpace = text.replace(/\s/g, '').length
const words = text.trim() === '' ? 0 : text.trim().split(/\s+/).length
const sentences = text.trim() === '' ? 0 : (text.match(/[.!?]+/g) ?? []).length
const paragraphs = text.trim() === ''
? 0
: text.split(/\n\s*\n/).filter(p => p.trim().length > 0).length
return {
total,
noSpace,
words,
sentences,
paragraphs,
readingMin: parseFloat((noSpace / 300).toFixed(1)), // 분당 300자
page200: parseFloat((noSpace / 200).toFixed(1)), // 200자 원고지
page400: parseFloat((noSpace / 400).toFixed(1)), // 400자 원고지
}
}
export function WordCounter() {
const [text, setText] = useState('')
// text 변경 시에만 재계산
const stats = useMemo(() => calcStats(text), [text])
const handlePaste = async () => {
const clipText = await navigator.clipboard.readText()
setText(clipText)
}
return (
<div>
{/* 툴바 */}
<button onClick={handlePaste}>붙여넣기</button>
<button onClick={() => setText('')}>초기화</button>
{/* 입력 영역 */}
<textarea
value={text}
onChange={e => setText(e.target.value)}
placeholder="텍스트를 입력하세요..."
style={{ minHeight: '200px' }}
/>
{/* 통계 카드 */}
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: '12px' }}>
<div>📝 {stats.total.toLocaleString()} 전체 글자</div>
<div>✂️ {stats.noSpace.toLocaleString()} 공백 제외</div>
<div>🔤 {stats.words.toLocaleString()} 단어</div>
<div>💬 {stats.sentences.toLocaleString()} 문장</div>
<div>📄 {stats.paragraphs.toLocaleString()} 문단</div>
<div>⏱️ {stats.readingMin}분 읽기 시간</div>
<div>📃 {stats.page200}매 200자 원고지</div>
<div>📋 {stats.page400}매 400자 원고지</div>
</div>
</div>
)
}2026년 5월 27일 게시